{"record":{"id":"7508a27881f89597","repo":"pinpoint-apm/pinpoint","slug":"invalid-pinpoint-header-type-headertype","errorCode":null,"errorMessage":"Invalid pinpoint header type - ${headerType}","messagePattern":"Invalid pinpoint header type - (.+?)","errorType":"exception","errorClass":"TProtocolException","httpStatus":null,"severity":"error","filePath":"agent-module/plugins/thrift/src/main/java/com/navercorp/pinpoint/plugin/thrift/ThriftRequestProperty.java","lineNumber":203,"sourceCode":"    \n    public void setAcceptorHost(String acceptorHost) {\n        this.thriftHeaders.put(ThriftHeader.THRIFT_HOST, acceptorHost);\n    }\n    \n    public void setTraceHeader(ThriftHeader headerKey, Object value) throws TException {\n        byte headerType = headerKey.getType();\n        if (headerType == TType.STRING) {\n            // skipped Strings are read as byte buffer.\n            // see org.apache.thrift.protocol.TProtocolUtil.skip(TProtocol, byte, int)\n            this.thriftHeaders.put(headerKey, byteBufferToString((ByteBuffer)value));\n        } else if (headerType == TType.I64) {\n            this.thriftHeaders.put(headerKey, (Long)value);\n        } else if (headerType == TType.I16) {\n            this.thriftHeaders.put(headerKey, (Short)value);\n        } else if (headerType == TType.BOOL) {\n            this.thriftHeaders.put(headerKey, (Boolean)value);\n        } else {\n            throw new TProtocolException(\"Invalid pinpoint header type - \" + headerType);\n        }\n    }\n    \n    public void writeTraceHeader(ThriftHeader headerKey, TProtocol oprot) throws TException {\n        Object headerValue = this.thriftHeaders.get(headerKey);\n        if (headerValue == null) {\n            return;\n        }\n        byte headerType = headerKey.getType();\n        TField traceField = new TField(headerKey.name(), headerKey.getType(), headerKey.getId());\n        oprot.writeFieldBegin(traceField);\n        try {\n            if (headerType == TType.STRING) {\n                // these will be read as byte buffer although it's probably safe to just use writeString here.\n                // see org.apache.thrift.protocol.TProtocolUtil.skip(TProtocol, byte, int)\n                oprot.writeBinary(stringToByteBuffer((String)headerValue));\n            } else if (headerType == TType.I64) {\n                oprot.writeI64((Long)headerValue);","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/plugins/thrift/src/main/java/com/navercorp/pinpoint/plugin/thrift/ThriftRequestProperty.java#L185-L221","documentation":"ThriftRequestProperty.setTraceHeader validates that the declared TType of a pinpoint propagation header matches a supported set (BYTE, I32, I64, I16, BOOL, STRING). If the headerType argument is any other Thrift type, it throws TProtocolException. This guards against writing propagation metadata with an incompatible wire type.","triggerScenarios":"Calling setTraceHeader(ThriftHeader, TType, Object) with a TType outside the supported list (e.g. TType.DOUBLE, TType.LIST) or a value whose runtime type does not match headerType, causing the cast/put branch chain to fall through to the else throw.","commonSituations":"Custom pinpoint header registration using a wrong TType constant; copy-paste of a ThriftHeader definition with the wrong type; version mismatch where a header was redefined to an unsupported type.","solutions":["Use only supported TTypes for pinpoint headers: BYTE, I32, I64, I16, BOOL, STRING","Verify each ThriftHeader constant's declared TType matches the value type you pass","Check plugin/version consistency between client and server propagation code","Log the offending headerType and fix the header definition"],"exampleFix":"// before\nrequest.setTraceHeader(ThriftHeader.HTTP_TRACE_ID, TType.DOUBLE, traceId);\n// after\nrequest.setTraceHeader(ThriftHeader.HTTP_TRACE_ID, TType.I64, traceId);","handlingStrategy":"validation","validationCode":"private static final Set<Byte> SUPPORTED = Set.of(TType.BYTE, TType.I32, TType.I64, TType.I16, TType.BOOL, TType.STRING);\nif (!SUPPORTED.contains(headerType)) {\n    throw new IllegalArgumentException(\"unsupported pinpoint header TType: \" + headerType);\n}\nif (value == null) {\n    throw new IllegalArgumentException(\"pinpoint header value must not be null\");\n}","typeGuard":"boolean isSupportedHeaderType(byte t) {\n    return t == TType.BYTE || t == TType.I32 || t == TType.I64 || t == TType.I16 || t == TType.BOOL || t == TType.STRING;\n}","tryCatchPattern":"try {\n    property.setTraceHeader(header, headerType, value);\n} catch (TProtocolException e) {\n    logger.warn(\"bad header type {} for {}\", headerType, header, e);\n}","preventionTips":["Define each ThriftHeader constant with its TType and value type together to keep them in sync","Only use TType constants from the supported list when registering pinpoint headers","Add a unit test that round-trips every custom header through setTraceHeader/writeTraceHeader","Keep agent/plugin versions consistent across services"],"tags":["thrift","serialization","header","validation"],"backgroundTag":"invalid-enum-value","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}