---
title: "startTunnel(options:completionHandler:)"
framework: networkextension
role: symbol
role_heading: Instance Method
path: "networkextension/nepackettunnelprovider/starttunnel(options:completionhandler:)"
---

# startTunnel(options:completionHandler:)

Start the network tunnel.

## Declaration

```swift
func startTunnel(options: [String : NSObject]? = nil, completionHandler: @escaping @Sendable ((any Error)?) -> Void)
```

```swift
func startTunnel(options: [String : NSObject]? = nil) async throws
```

## Parameters

- `options`: A dictionary passed by the app that requested that the tunnel be started. If the starting app did not specify a dictionary of options then this parameter will be nil. If the tunnel was started via Connect On Demand, then this parameter will be nil.
- `completionHandler`: A block that must be executed when the tunnel is fully established, or when the tunnel cannot be started due to an error. If the tunnel was successfully established, then the error parameter must be set to nil. If an error occurred, the error parameter passed to this block must be set to a non-nil doc://com.apple.documentation/documentation/Foundation/NSError object.

## Discussion

Discussion This method is called by the system to start the network tunnel. NEPacketTunnelProvider subclasses must override this method. When the Packet Tunnel Provider executes the completionHandler block with a nil error parameter, it signals to the system that it is ready to begin handling network data. Therefore, the Packet Tunnel Provider should call setTunnelNetworkSettings(_:completionHandler:) and wait for it to complete before executing the completionHandler block. The domain and code of the NSError object passed to the completionHandler block are defined by the Packet Tunnel Provider.

## See Also

### Managing the tunnel life cycle

- [stopTunnel(with:completionHandler:)](networkextension/nepackettunnelprovider/stoptunnel(with:completionhandler:).md)
- [cancelTunnelWithError(_:)](networkextension/nepackettunnelprovider/canceltunnelwitherror(_:).md)
