{"record":{"id":"7bb917364bf4e389","repo":"Netflix/zuul","slug":"received-invalid-message-from-origin","errorCode":null,"errorMessage":"Received invalid message from origin","messagePattern":"Received invalid message from origin","errorType":"exception","errorClass":"ZuulException","httpStatus":null,"severity":"error","filePath":"zuul-core/src/main/java/com/netflix/zuul/netty/server/ClientResponseWriter.java","lineNumber":150,"sourceCode":"                channel.write(buildHttpResponse(zuulResponse));\n                writeBufferedBodyContent(zuulResponse, channel);\n                channel.flush();\n            } else {\n                resp.disposeBufferedBody();\n                channel.close();\n            }\n        } else if (msg instanceof HttpContent chunk) {\n\n            if (channel.isActive()) {\n                channel.writeAndFlush(chunk);\n            } else {\n                chunk.release();\n                channel.close();\n            }\n        } else {\n            // should never happen\n            ReferenceCountUtil.release(msg);\n            throw new ZuulException(\"Received invalid message from origin\", true);\n        }\n    }\n\n    protected boolean shouldAllowPreemptiveResponse(Channel channel) {\n        // If the request timed-out while being read, then there won't have been any LastContent, but that's ok because\n        // the connection will have to be discarded anyway.\n        StatusCategory status =\n                StatusCategoryUtils.getStatusCategory(ClientRequestReceiver.getRequestFromChannel(channel));\n        return status == ZuulStatusCategory.FAILURE_CLIENT_TIMEOUT;\n    }\n\n    protected boolean skipProcessing(HttpResponseMessage resp) {\n        // override if you need to skip processing of response\n        return false;\n    }\n\n    protected void writeBufferedBodyContent(HttpResponseMessage zuulResponse, Channel channel) {\n        zuulResponse.getBodyContents().forEach(chunk -> channel.write(chunk.retain()));","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/Netflix/zuul/blob/14bf53c52dcf571894619ff65a674cbe2cce3ac6/zuul-core/src/main/java/com/netflix/zuul/netty/server/ClientResponseWriter.java#L132-L168","documentation":"ClientResponseWriter.channelRead receives messages coming back from the origin through the client-facing pipeline and only recognizes valid Zuul HTTP response messages (HttpResponse start plus HttpContent chunks). Any other message type from the origin side is released and this ZuulException is thrown, because Zuul cannot safely forward it to the client. Like the sibling checks, it is an internal invariant guard labeled 'should never happen'.","triggerScenarios":"A message that is neither an expected origin response type (e.g. not an HttpResponse/HttpContent/ZuulMessage instance) arrives at ClientResponseWriter.channelRead — caused by a custom origin filter/handler injecting a foreign object, or a pipeline wiring change passing unexpected messages downstream.","commonSituations":"Custom origin-side filters returning raw objects; in-flight Netty or zuul-core upgrades changing message types; misconfigured channel pipelines where a handler between origin and client emits its own message types.","solutions":["Identify which component injected the unexpected message by adding a logging handler on the response pipeline to print msg.getClass().","Fix the custom origin filter/handler to emit proper Zuul/Netty HTTP response types (HttpResponse, HttpContent).","Review recent pipeline customizations (ClientRequestReceiver/Netty channel init) for handlers inserted between the origin response receiver and the client writer.","Pin/align zuul-core and custom filter dependencies to a consistent version so response message types match expectations."],"exampleFix":"// before (custom origin handler)\nctx.fireChannelRead(myCustomObject);\n// after\nctx.fireChannelRead(new DefaultLastHttpContent()); // proper Netty/Zuul response content types only","handlingStrategy":"validation","validationCode":"// before forwarding origin messages downstream, ensure they are valid HTTP response types\nif (!(msg instanceof HttpResponse || msg instanceof HttpContent)) {\n    throw new IllegalArgumentException(\"Unsupported origin message: \" + msg.getClass().getName());\n}","typeGuard":"boolean isValidOriginMessage(Object msg) {\n    return msg instanceof HttpResponse || msg instanceof HttpContent;\n}","tryCatchPattern":"try {\n    // pipeline read path\n} catch (ZuulException e) {\n    if (\"Received invalid message from origin\".equals(e.getMessage())) {\n        log.error(\"Origin pipeline emitted non-HTTP message\", e);\n        channel.close();\n    }\n}","preventionTips":["Custom origin-side handlers must only fire HttpResponse/HttpContent messages","Test custom pipelines with a wire-logging handler to spot foreign message types","Keep zuul-core and Netty versions consistent across custom handlers","Avoid inserting handlers between origin receiver and client writer that emit custom objects"],"tags":["netty","zuul-filter","internal-invariant","origin-response"],"backgroundTag":"internal-invariant-violation","analyzedSha":"14bf53c52dcf571894619ff65a674cbe2cce3ac6","analyzedAt":"2026-09-07T10:00:54.873Z","contentChangedAt":"2026-09-07T10:00:54.873Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}