{"record":{"id":"d04b1ee23731501c","repo":"discordjs/discord.js","slug":"malformed-ip-address","errorCode":null,"errorMessage":"Malformed IP address","messagePattern":"Malformed IP address","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/voice/src/networking/VoiceUDPSocket.ts","lineNumber":26,"sourceCode":" * for Discord.\n */\nexport interface SocketConfig {\n\tip: string;\n\tport: number;\n}\n\n/**\n * Parses the response from Discord to aid with local IP discovery.\n *\n * @param message - The received message\n */\nexport function parseLocalPacket(message: Buffer): SocketConfig {\n\tconst packet = Buffer.from(message);\n\n\tconst ip = packet.subarray(8, packet.indexOf(0, 8)).toString('utf8');\n\n\tif (!isIPv4(ip)) {\n\t\tthrow new Error('Malformed IP address');\n\t}\n\n\tconst port = packet.readUInt16BE(packet.length - 2);\n\n\treturn { ip, port };\n}\n\n/**\n * The interval in milliseconds at which keep alive datagrams are sent.\n */\nconst KEEP_ALIVE_INTERVAL = 5e3;\n\n/**\n * The maximum value of the keep alive counter.\n */\nconst MAX_COUNTER_VALUE = 2 ** 32 - 1;\n\nexport interface VoiceUDPSocket extends EventEmitter {","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/discordjs/discord.js/blob/a81ed8a306d37fdc746e26a634b6a42164ba2c8c/packages/voice/src/networking/VoiceUDPSocket.ts#L8-L44","documentation":"parseLocalPacket parses the UDP IP-discovery response that Discord sends so the client can learn its local IP/port for voice. It extracts the IP from bytes 8..first-null of the 74-byte packet and validates it with node:net's isIPv4; if the extracted bytes are not a valid IPv4 address it throws this Error. This means the discovery response was malformed or the packet framing changed.","triggerScenarios":"Receiving a UDP discovery (SELECT_PROTOCOL READY) response whose bytes 8..N do not form a valid IPv4 string — e.g. a truncated packet, a response from a non-Discord/intercepting server, or networking middleware rewriting the payload.","commonSituations":"Running voice traffic through a VPN/proxy/corporate firewall that mangles UDP; custom Discord API mocks returning a wrongly shaped discovery payload; rare Discord-side protocol changes; packet corruption on flaky networks.","solutions":["Retry the voice connection (destroy and rejoin the voice channel) — transient UDP corruption is the most common cause.","Check VPN, proxy, and firewall setups that intercept or rewrite UDP packets and try a direct connection.","Verify the UDP socket is actually talking to the gateway-provided IP (see VoiceUDPSocket) and not an interception layer.","Update @discordjs/voice in case of a protocol/framing change; report if it persists."],"exampleFix":"// before\nawait connection.connect(); // may throw 'Malformed IP address' behind a VPN\n// after\ntry {\n  await connection.connect();\n} catch (e) {\n  connection.destroy(); // then rejoin to retry the UDP discovery handshake\n}","handlingStrategy":"retry","validationCode":"// Validate the discovery response yourself if you handle raw UDP:\nconst net = require('node:net');\nif (!net.isIPv4(ip)) { /* rejoin / retry instead of proceeding */ }","typeGuard":"function isValidLocalPacket(cfg: { ip: string; port: number }): boolean {\n  return net.isIPv4(cfg.ip) && cfg.port > 0 && cfg.port <= 65535;\n}","tryCatchPattern":"try {\n  await connection.connect();\n} catch (e) {\n  if (e.message === 'Malformed IP address') {\n    connection.destroy();\n    await joinVoiceChannel(channelConfig); // retry discovery once or twice\n  } else throw e;\n}","preventionTips":["Avoid VPNs/proxies that intercept UDP for the bot process; allowlist Discord UDP endpoints in firewalls.","Keep the voice connection lifecycle managed (destroy on failure) so discovery can be retried cleanly.","Keep @discordjs/voice updated for protocol framing changes.","Run with a stable network — check packet loss if this error recurs."],"tags":["udp","network","voice","packet-parsing"],"backgroundTag":"malformed-packet-response","analyzedSha":"a81ed8a306d37fdc746e26a634b6a42164ba2c8c","analyzedAt":"2026-08-30T04:07:22.193Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}