{"record":{"id":"b2e87aed5c639a09","repo":"router-for-me/CLIProxyAPI","slug":"claude-oauth-tls-apply-clienthello-w","errorCode":null,"errorMessage":"claude oauth tls: apply ClientHello: %w","messagePattern":"claude oauth tls: apply ClientHello: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/auth/claude/utls_transport.go","lineNumber":227,"sourceCode":"\t\tconn, err = t.dialer.Dial(network, addr)\n\t}\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"claude oauth tls: dial upstream: %w\", err)\n\t}\n\n\thost, _, errSplit := net.SplitHostPort(addr)\n\tif errSplit != nil {\n\t\tif errClose := conn.Close(); errClose != nil {\n\t\t\tlog.Debugf(\"claude oauth tls: close failed connection: %v\", errClose)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"claude oauth tls: split upstream address: %w\", errSplit)\n\t}\n\ttlsConn := tls.UClient(conn, newClaudeOAuthTLSConfig(host, t.sessionCache), tls.HelloCustom)\n\tif errPreset := tlsConn.ApplyPreset(claudeOAuthTLSClientHelloSpec()); errPreset != nil {\n\t\tif errClose := tlsConn.Close(); errClose != nil {\n\t\t\tlog.Debugf(\"claude oauth tls: close connection after preset failure: %v\", errClose)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"claude oauth tls: apply ClientHello: %w\", errPreset)\n\t}\n\thandshakeCtx := ctx\n\tif handshakeTimeout, _ := ctx.Value(claudeRefreshHandshakeTimeoutContextKey{}).(time.Duration); handshakeTimeout > 0 {\n\t\tvar cancelHandshake context.CancelFunc\n\t\thandshakeCtx, cancelHandshake = context.WithTimeout(ctx, handshakeTimeout)\n\t\tdefer cancelHandshake()\n\t}\n\tif errHandshake := tlsConn.HandshakeContext(handshakeCtx); errHandshake != nil {\n\t\tif errClose := tlsConn.Close(); errClose != nil {\n\t\t\tlog.Debugf(\"claude oauth tls: close connection after handshake failure: %v\", errClose)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"claude oauth tls: handshake upstream: %w\", errHandshake)\n\t}\n\treturn httpwire.NewOrderedRequestConn(tlsConn, claudeOAuthRequestHeaderOrder), nil\n}\n\nfunc (t *utlsRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {\n\treturn t.transport.RoundTrip(req)","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/auth/claude/utls_transport.go#L209-L245","documentation":"tls.UClient was constructed but ApplyPreset(claudeOAuthTLSClientHelloSpec()) rejected the ClientHello specification used to mimic Claude Code's TLS fingerprint. The spec is a fixed in-code structure; a failure means the compiled uTLS library considers it invalid — effectively a build/version mismatch, not a runtime condition.","triggerScenarios":"Building the binary against an incompatible github.com/refraction-networking/utls version whose ClientHelloSpec fields/expectations changed; hand-edited fingerprint specs in forks; spec structs zeroed by unusual build flags. Never depends on the remote server or network.","commonSituations":"go.mod upgraded (or downgraded) utls transitively so the vendored spec no longer validates; forks that tweak claudeOAuthTLSClientHelloSpec; mixed module cache states after partial upgrades.","solutions":["Restore the utls version pinned by this repo's go.mod (go mod tidy with the committed go.sum).","If you maintain a fork, re-validate your ClientHelloSpec against the utls version you build with (fields like CipherSuites/Extensions changed across releases).","File an issue with the repo including your utls version if the stock build fails here."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// at build time: ensure the utls version matches the pinned one\n// go mod verify && go mod tidy","typeGuard":null,"tryCatchPattern":"if errPreset := tlsConn.ApplyPreset(spec); errPreset != nil {\n    // binary was built against an incompatible utls: rebuild with the repo's go.mod pins\n    return fmt.Errorf(\"rebuild with pinned dependencies: %w\", errPreset)\n}","preventionTips":["Never bump github.com/refraction-networking/utls independently of this repo's go.mod.","After any dependency change, run the OAuth transport tests before shipping."],"tags":["claude","oauth","tls","build","version-mismatch"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}