# Cannot send URLProtocol subclass across actor boundary

**URL:** <https://forums.swift.org/t/cannot-send-urlprotocol-subclass-across-actor-boundary/82277>\
**Category:** Foundation\
**Tags:** concurrency, sendable, unchecked, nsobject, urlprotocol\
**Created:** [September 22, 2025, 9:52am UTC](https://forums.swift.org/t/cannot-send-urlprotocol-subclass-across-actor-boundary/82277 "2025-09-22T09:52:45Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![andreabou](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/andreabou/32/37722_2.png) [@andreabou](https://forums.swift.org/u/andreabou)\
**Post date:** [September 22, 2025, 9:52am UTC](https://forums.swift.org/t/cannot-send-urlprotocol-subclass-across-actor-boundary/82277/1 "2025-09-22T09:52:45Z")

</div>

Hello fellow nerds,

I came across this very annoying compilation error after upgrading to Xcode 26.0 and Swift 6.2.

Say you have this **actor** :

```swift
import Foundation

@globalActor
actor MyActor: GlobalActor {
    static let shared: MyActor = .init()
}

```

Now say you want to implement a subclass of `URLProtocol` just to mock some network calls.

### Example 1:

```swift
final class NoSendableURLProtocol: URLProtocol {
    final override func startLoading() {
        Task { @MyActor [weak self] in
            guard let self else { return } // error: Sending 'self' risks causing data races
        }
    }
}

```

### Example 2:

```swift
@MyActor
final class ActorURLProtocol: URLProtocol {
    final override func startLoading() {
        Task { @MyActor [weak self] in
            guard let self else { return } // error: Sending 'self' risks causing data races
        }
    }
}

```

### Example 3:

```swift
@preconcurrency
final class PreconcurrencyURLProtocol: URLProtocol {
    final override func startLoading() {
        Task { @MyActor [weak self] in
            guard let self else { return } // error: Sending 'self' risks causing data races
        }
    }
}

```

### Example 4:

```swift
final class SendableURLProtocol: URLProtocol, Sendable { // 'Sendable' class 'SendableURLProtocol' cannot inherit from another class other than 'NSObject'
    final override func startLoading() {
        Task { @MyActor [weak self] in
            guard let self else { return } // error: same as before
        }
    }
}

```

### Example 5:

```swift
@preconcurrency
final class UncheckedSendableURLProtocol: URLProtocol, @unchecked Sendable { // Conformance of 'UncheckedSendableURLProtocol' to protocol 'Sendable' is already unavailable
    final override func startLoading() {
        Task { @MyActor [weak self] in
            guard let self else { return } // error: same as before
        }
    }
}

```

### Example 6:

```swift
final class WorkingURLProtocol: URLProtocol, @unchecked Sendable {
    final override func startLoading() {
        Task { @MyActor [request = task?.originalRequest, requestURL = task?.originalRequest?.url, client] in
            guard let request, let requestURL else {
                fatalError()
            }

            defer {
                client?.urlProtocolDidFinishLoading(self)
            }

            // A whole lot of code, so that the compiler "forgets" to check that `self` is being sent

            client?.urlProtocol(self, didLoad: .init())
        }
    }
}

```

In a Playground, I can't get this to work actually, but I can in a project of mine. Can't share the code unfortunately, but I guarantee you the compiler "stops caring" at one point.

* * *

**Example #4** above led me to [this post](https://forums.swift.org/t/sendable-class-abc-cannot-inherit-from-another-class-other-than-nsobject/57197), which doesn’t really address the issue.

It seems to me that subclasses of `NSObject` that are themselves not `final` cause the sendable checks to go nuts. So a subclass of a subclass (ie. `MyProtocol: URLProtocol: NSObject`) does not play well with `Sendable`.

### TLDR

What is a bug in my opinion though, is that marking it as `@unchecked Sendable` does nothing, neither does `@preconcurrency`.

* * *

#### Extra bits:

- Xcode Version 26.0 (17A324)
- `swift-driver version: 1.127.14.1 Apple Swift version 6.2 (swiftlang-6.2.0.19.9 clang-1700.3.19.1)`

---

<div class="post-metadata">

**Author:** ![jmschonfeld](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jmschonfeld/32/20922_2.png) [@jmschonfeld](https://forums.swift.org/u/jmschonfeld)\
**Post date:** [September 22, 2025, 4:39pm UTC](https://forums.swift.org/t/cannot-send-urlprotocol-subclass-across-actor-boundary/82277/2 "2025-09-22T16:39:13Z")

</div>

I believe the root cause of this bug is hinted at by this error message:

> [@andreabou](#):
>
> ```swift
> final class UncheckedSendableURLProtocol: URLProtocol, @unchecked Sendable { // Conformance of 'UncheckedSendableURLProtocol' to protocol 'Sendable' is already unavailable
> 
> ```

The error message notes that the `Sendable` conformance is already unavailable, and I believe that’s coming from the imported `URLProtocol` type itself. On Darwin it’s marked as explicitly unavailable by nature of it being in a `NS_HEADER_AUDIT_BEGIN(sendability)` block and on Linux/Windows the conformance is explicitly marked as unavailable in the Swift source. I will need to check, but I _think_ this is incorrect - I think that `URLProtocol` should be neither explicitly `Sendable` nor non-`Sendable` and should instead leave its `Sendable` conformance up to subclasses (I’ll need to double check on whether that’s indeed the case or if `URLProtocol` has some part of it that prevents `Sendable` conformances even in subclasses). The already-existing unavailable `Sendable` conformance is why you can’t add a `Sendable` conformance of your own.

cc @hborla - I believe this is the same category as the `DateFormatter` Sendable conformance where we don’t yet have a great way to import an Objective-C type as “potentially `Sendable`".
