Skip to content

Concept in Capabilities

ERR_LOCAL_NETWORK_PERMISSION_MISSING in Chrome

Published

Limited availabilityNot supported in Firefox (Desktop), Firefox (Android), Safari (macOS), Safari (iOS)WICG draft

Local Network Access errors occur when a public page requests a local or loopback destination and Chrome cannot continue under the permission and address-space checks. Page JavaScript usually receives a rejected fetch() promise. DevTools can expose a more specific Chromium network error.

Chrome launched the Local Network Access permission prompt in Chrome 142. The Chrome announcement documents fetch() and subresource loads for the initial restrictions. It covers subframe navigation too. The specification defines secure-context and permission checks. It also defines policy and target-address-space checks. BCD support records for Request.targetAddressSpace include Chrome 142 and mirrored Chromium derivatives; the compatibility data lists the full support range. BCD records no support in Firefox or Safari.

A request from a public address space to a local or loopback destination is a local network request under the first Chrome milestone. The specification requires a secure client with an associated document. Permission-policy access and a grant for local-network or loopback-network are also required. If the permission state is prompt, the user agent asks the user. It continues only after a grant.

The fetch API does not expose Chromium’s internal network code as a structured JavaScript value. A rejected fetch() is therefore the start of diagnosis, not proof that permission was denied. Check DevTools and the request URL. Then check the page’s security context and response CORS headers. Verify whether the destination responds.

Signal Meaning documented by the source Next check
net::ERR_LOCAL_NETWORK_PERMISSION_MISSING Chromium blocked the request because local-network permission is missing Ask the user to review the site’s local-network permission
net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS Chromium blocked the connection in the Local Network Access checks and reserves this code for the CORS error path Compare the declared and resolved address spaces and inspect policy
JavaScript TypeError from fetch() Fetch ended in a network error Use DevTools and server logs to distinguish permission from CORS. Check mixed content separately. Then check DNS failures and refused connections before inspecting timeouts
No permission prompt The request may have failed before prompting or the document may not be allowed to prompt Check the secure context and document ownership. Then inspect Permissions Policy

targetAddressSpace: "local" or "loopback" declares the intended destination. The specification lets this declaration bypass the relevant mixed-content upgrade step. It then compares the resolved address with the declaration. A mismatch returns a network error. The option is a declaration and guard; it does not grant permission and does not add CORS response headers to the device.

Workers require special care. The current specification’s local-network-access check returns a network error when the request has no associated Document. Its note identifies service workers as affected. Chromium issue 404887282 tracks Local Network Access behavior for service workers. Obtain the required grant from a document flow before moving network work into a worker. Retain a document-side fallback.

Failure boundary What to change
Permission denied or missing Explain why the connection is needed and let the user retry after changing the site permission
Permissions Policy blocks an iframe Delegate local-network or loopback-network to the intended frame; Chromium also exposes a combined alias
Address-space declaration mismatches DNS Correct targetAddressSpace or the hostname; do not weaken it to reach a public destination
Device omits CORS permission Configure the device’s HTTP response for the requesting origin
Device is offline or refuses the connection Offer device setup and connectivity checks
Browser lacks targetAddressSpace Use an HTTPS endpoint or a browser-supported device capability instead of assuming the Chrome path

Both examples start from a secure document. They return application states instead of claiming that a JavaScript TypeError identifies one network cause.

Declaring a local target and preserving the rejection

Section titled “Declaring a local target and preserving the rejection”

Feature detection keeps the Chrome-specific request member off the unsupported path. The catch branch records the error name and tells the UI that diagnosis is still required.

<label>
Device status URL
<input id="device-url" type="url" value="http://192.168.1.1/status">
</label>
<button id="read-device" type="button">Read status</button>
<output id="read-result" aria-live="polite"></output>
<script>
async function readDeviceStatus(url = 'http://192.168.1.1/status') {
if (!window.isSecureContext) {
return { ok: false, reason: 'secure-context-required' };
}
if (!('targetAddressSpace' in Request.prototype)) {
return { ok: false, reason: 'address-space-option-unsupported' };
}
try {
const response = await fetch(url, {
targetAddressSpace: 'local',
});
if (!response.ok) return { ok: false, reason: `http-${response.status}` };
return { ok: true, data: await response.json() };
} catch (error) {
return { ok: false, reason: 'network-error', errorName: error.name };
}
}
const readButton = document.querySelector('#read-device');
const deviceUrl = document.querySelector('#device-url');
const readResult = document.querySelector('#read-result');
if (readButton && deviceUrl && readResult) {
readButton.addEventListener('click', async () => {
readButton.disabled = true;
const result = await readDeviceStatus(deviceUrl.value);
readResult.textContent = JSON.stringify(result);
readButton.disabled = false;
});
}
</script>

The UI can now separate setup failures from an HTTP response. DevTools or managed telemetry must supply the Chromium network code if support staff need to distinguish permission from address-space checks.

Retrying from a document after a worker failure

Section titled “Retrying from a document after a worker failure”

A service worker has no reliable prompt surface under the current specification note. This message handler returns control to the document. A click can then issue the request and allow Chrome to display permission UI.

<button id="retry-device" type="button" hidden>Retry device connection</button>
<output id="device-result" aria-live="polite"></output>
<script>
const retryButton = document.querySelector('#retry-device');
const deviceResult = document.querySelector('#device-result');
function renderDeviceResult(result) {
if (!deviceResult) return;
deviceResult.textContent = result.ok
? JSON.stringify(result.data)
: `Device request stopped: ${result.reason}`;
}
if (retryButton) {
retryButton.addEventListener('click', async () => {
if (retryButton.disabled) return;
retryButton.disabled = true;
const result = await readDeviceStatus();
renderDeviceResult(result);
retryButton.hidden = result.ok;
retryButton.disabled = false;
});
}
navigator.serviceWorker.addEventListener('message', (event) => {
if (event.data?.type !== 'local-network-retry-required') return;
if (!retryButton) return;
retryButton.hidden = false;
});
async function requestFromWorker() {
const controller = navigator.serviceWorker.controller;
if (!controller) return readDeviceStatus();
controller.postMessage({ type: 'read-local-device' });
return { ok: false, reason: 'delegated-to-worker' };
}
requestFromWorker().then(renderDeviceResult);
</script>

The worker should post local-network-retry-required after its request rejects. The document does not promise that retrying will succeed. CORS and an address mismatch can still produce a network error. An unreachable device can produce one too. The Web Bluetooth compatibility data provides a separate permission-mediated route for devices that expose Bluetooth instead of an HTTP server.

Specifications

SpecificationStatus
Local Network Access (Request.targetAddressSpace)WICG draft
  • Legend
  • Yes
  • Partial
  • Flag
  • No
  • Unknown
Browser / PlatformSupportVersionsConfidenceSourceNotes
Chrome (Desktop)#Yes142highsource—
Chrome (Android)#Yes142highsource1
Edge (Desktop)#Yes142highsource2
Firefox (Desktop)#No—highsource3
Firefox (Android)#No—highsource45
Safari (macOS)#No—highsource6
Safari (iOS)#No—highsource78
Samsung Internet#Yes30.0highsource9
WebView (Android)#No—highsource10
  1. Derived by browser-compat-data mirroring from Chrome.
  2. Derived by browser-compat-data mirroring from Chrome.
  3. No Firefox support is recorded in browser-compat-data.
  4. No Firefox for Android support is recorded in browser-compat-data.
  5. Derived by browser-compat-data mirroring from Firefox.
  6. No Safari support is recorded in browser-compat-data.
  7. No Safari on iOS support is recorded in browser-compat-data.
  8. Derived by browser-compat-data mirroring from Safari.
  9. Derived by browser-compat-data mirroring from Chrome Android.
  10. No WebView Android support is recorded in browser-compat-data.

Source data: /compatibility/local-network-access.json · Global usage: 75 % (StatCounter 2026-09, CC BY-SA 4.0)

Source: spec · MDN · Last verified 2026-10-28 · Confidence: high (computed from sources)