{"record":{"id":"80f870aed2a462e2","repo":"tauri-apps/tauri","slug":"ipc-custom-protocol-failed-tauri-will-now-use-the","errorCode":null,"errorMessage":"IPC custom protocol failed, Tauri will now use the postMessage interface instead","messagePattern":"IPC custom protocol failed, Tauri will now use the postMessage interface instead","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/tauri/scripts/ipc-protocol.js","lineNumber":60,"sourceCode":"        .then((response) => {\n          const callbackId =\n            response.headers.get('Tauri-Response') === 'ok' ? callback : error\n          // we need to split here because on Android the content-type gets duplicated\n          switch ((response.headers.get('content-type') || '').split(',')[0]) {\n            case 'application/json':\n              return response.json().then((r) => [callbackId, r])\n            case 'text/plain':\n              return response.text().then((r) => [callbackId, r])\n            default:\n              return response.arrayBuffer().then((r) => [callbackId, r])\n          }\n        })\n        .then(\n          ([callbackId, data]) => {\n            window.__TAURI_INTERNALS__.runCallback(callbackId, data)\n          },\n          (e) => {\n            console.warn(\n              'IPC custom protocol failed, Tauri will now use the postMessage interface instead',\n              e\n            )\n            // failed to use the custom protocol IPC (either the webview blocked a custom protocol or it was a CSP error)\n            // so we need to fallback to the postMessage interface\n            customProtocolIpcFailed = true\n            sendIpcMessage(message)\n          }\n        )\n    } else {\n      // otherwise use the postMessage interface\n      const { data } = processIpcMessage({\n        cmd,\n        callback,\n        error,\n        options: {\n          ...options,\n          customProtocolIpcBlocked: customProtocolIpcFailed","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/tauri-apps/tauri/blob/52e4b6e71d8632a7e648f866c442e287ecddee34/crates/tauri/scripts/ipc-protocol.js#L42-L78","documentation":"On non-Android platforms sendIpcMessage first POSTs to Tauri's custom IPC protocol (ipc://localhost, exposed as http://ipc.localhost) via fetch, carrying the serialized payload and callback ids in headers. If that fetch rejects — typically because the page CSP blocks the request or the webview refuses the custom protocol — Tauri logs this warning, sets customProtocolIpcFailed = true and transparently re-sends the message over the postMessage transport. IPC keeps working; the cost is the slower transport, which matters for large payloads.","triggerScenarios":"A CSP whose connect-src lacks ipc: http://ipc.localhost (custom security.csp, or dangerousDisableAssetCspModification: true without adding them manually); remote or iframe content whose origin cannot fetch the custom protocol; WebView configurations that block custom-scheme fetches. The warn fires on the first failed fetch, after which every message uses postMessage.","commonSituations":"Setting a hand-written csp string in tauri.conf.json and forgetting connect-src ipc entries; disabling Tauri's automatic CSP injection; loading remote URLs in the webview; the warning appearing only on some platforms or only inside iframes.","solutions":["Add ipc: http://ipc.localhost to connect-src of security.csp in tauri.conf.json.","If dangerousDisableAssetCspModification is true, add those source expressions yourself to the served document's CSP.","Verify in devtools that the fetch to ipc://localhost (http://ipc.localhost) no longer fails; the warning should disappear on the next run.","If the environment genuinely cannot use the custom protocol, accept the automatic postMessage fallback — but keep invoke payloads small or move bulk transfers to the asset protocol to avoid its overhead."],"exampleFix":"// before: tauri.conf.json — custom CSP drops the IPC source expressions\n{\n  \"security\": {\n    \"csp\": \"default-src 'self'; connect-src 'self'\"\n  }\n}\n\n// after: connect-src allows the custom IPC protocol\n{\n  \"security\": {\n    \"csp\": \"default-src 'self'; connect-src 'self' ipc: http://ipc.localhost\"\n  }\n}","handlingStrategy":"fallback","validationCode":"// Optional pre-flight: probe whether the custom IPC protocol is\n// reachable before relying on it for large payloads\nfetch(window.__TAURI_INTERNALS__.convertFileSrc('probe', 'ipc'), { method: 'HEAD' })\n  .then(() => console.info('custom IPC protocol available'))\n  .catch(() => console.warn('IPC will use the postMessage fallback'))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include ipc: http://ipc.localhost in the connect-src of security.csp in tauri.conf.json.","If setting dangerousDisableAssetCspModification: true, add the IPC source expressions to the document CSP yourself.","Check devtools network/console after changing CSP to confirm the ipc://localhost fetch succeeds.","Design IPC payloads small; if forced onto the postMessage fallback, move bulk data to the asset protocol or custom protocol endpoints."],"tags":["ipc","csp","custom-protocol","postmessage","javascript","config"],"backgroundTag":"custom-protocol-blocked","analyzedSha":"52e4b6e71d8632a7e648f866c442e287ecddee34","analyzedAt":"2026-08-20T13:59:20.734Z","contentChangedAt":"2026-08-20T13:59:20.734Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}