MagicMirrorOrg/MagicMirror · warning
Failed to parse client IP: ${clientIp}
Error message
Failed to parse client IP: ${clientIp} What it means
isAllowed first parses the incoming client IP with ipaddr.process. If the client IP string cannot be parsed (the whole function is wrapped in try/catch), this warning is logged and access is denied, returning false. It guards against malformed or unusual address representations coming from the request layer.
Source
Thrown at js/ip_access_control.js:31
return whitelist.some((entry) => {
try {
// CIDR notation
if (entry.includes("/")) {
const [rangeAddr, prefixLen] = ipaddr.parseCIDR(entry);
return addr.match(rangeAddr, prefixLen);
}
// Single IP address - let ipaddr.process normalize both
const allowedAddr = ipaddr.process(entry);
return addr.toString() === allowedAddr.toString();
} catch {
Log.warn(`Invalid whitelist entry: ${entry}`);
return false;
}
});
} catch {
Log.warn(`Failed to parse client IP: ${clientIp}`);
return false;
}
}
/**
* Resolves a client IP for both Express and Socket.IO requests.
* If the direct peer is loopback, trust the first X-Forwarded-For value (local reverse proxy case).
* Otherwise ignore X-Forwarded-For to prevent spoofing.
* @param {object} req - Incoming request object (Express request or Socket.IO handshake request)
* @returns {string} The resolved client IP address
*/
function resolveClientIp (req) {
const directIp = req.socket?.remoteAddress || req.connection?.remoteAddress || req.ip;
const LOOPBACK_WHITELIST = ["127.0.0.1", "::ffff:127.0.0.1", "::1"];
if (isAllowed(directIp, LOOPBACK_WHITELIST)) {
const forwardedFor = req.headers?.["x-forwarded-for"];
if (typeof forwardedFor === "string" && forwardedFor.trim().length > 0) {View on GitHub (pinned to 4b4a59534f)
Solutions
- Inspect what resolveClientIp returns — log or debug the raw headers (X-Forwarded-For, X-Real-IP) and fix the proxy sending them.
- Sanitize/strip the forwarded header chain so only valid IPs remain, or trust only known proxy IPs.
- If the source is a local/test client, ensure the test passes a real IP string like '127.0.0.1'.
- Adjust the resolution logic in ip_access_control.js to try req.socket.remoteAddress before forwarded headers.
Example fix
// before (proxy) proxy_set_header X-Forwarded-For "$http_x_forwarded_for, unknown"; // after proxy_set_header X-Forwarded-For $remote_addr;
Defensive patterns
Strategy: type-guard
Validate before calling
const ipaddr = require("ipaddr.js");
function safeResolveClientIp(req) {
const fwd = req.headers["x-forwarded-for"];
const candidates = [fwd?.split(",")[0]?.trim(), req.socket?.remoteAddress].filter(Boolean);
return candidates.find(c => { try { ipaddr.process(c); return true; } catch { return false; } }) ?? null;
} Type guard
function isValidClientIp(ip) {
if (typeof ip !== "string" || ip.length === 0) return false;
try { ipaddr.process(ip); return true; } catch { return false; }
} Try / catch
try {
isAllowed(clientIp, whitelist);
} catch {
Log.warn(`Failed to parse client IP: ${clientIp}; denying request`);
return false;
} Prevention
- Configure your reverse proxy to send a clean X-Forwarded-For with $remote_addr.
- Strip or ignore garbage segments in the forwarded chain before parsing.
- Log raw headers once when debugging access issues to see what the parser receives.
When it happens
Trigger: resolveClientIp produces a client IP string that ipaddr.process cannot parse — e.g. corrupted X-Forwarded-For headers containing garbage, unexpected unix-socket peer addresses, or '::ffff:' forms combined with invalid data.
Common situations: Reverse proxies injecting malformed X-Forwarded-For values; requests over abstract sockets or unusual transports in tests; spoofed headers from hostile clients; IPv6-mapped edge cases not handled by the caller.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Forbidden: private or reserved addresses are not allowed
- Invalid whitelist entry: ${entry}
- IP ${clientIp} is not allowed to connect to the mirror socke
- <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8
- CORS proxy is disabled
AI-assisted analysis of MagicMirrorOrg/MagicMirror@4b4a59534f (2026-08-31).
Data as JSON: /api/errors/88b4c4a91df130cc.
Report an issue: GitHub.