{"record":{"id":"1a9d6157539f1b75","repo":"apache/pulsar","slug":"invalid-messageid-base64-value","errorCode":null,"errorMessage":"Invalid messageId base64 value","messagePattern":"Invalid messageId base64 value","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-websocket/src/main/java/org/apache/pulsar/websocket/ReaderHandler.java","lineNumber":399,"sourceCode":"        int size = DEFAULT_RECEIVER_QUEUE_SIZE;\n        if (queryParams.containsKey(\"receiverQueueSize\")) {\n            size =  Math.min(Integer.parseInt(queryParams.get(\"receiverQueueSize\")), DEFAULT_RECEIVER_QUEUE_SIZE);\n        }\n        return size;\n    }\n\n    private MessageId getMessageId() {\n        MessageId messageId = MessageId.latest;\n        String messageIdParam = queryParams.get(\"messageId\");\n        if (isNotBlank(messageIdParam)) {\n            if (messageIdParam.equals(\"earliest\")) {\n                messageId = MessageId.earliest;\n            } else if (!messageIdParam.equals(\"latest\")) {\n                final byte[] decoded;\n                try {\n                    decoded = Base64.getDecoder().decode(messageIdParam);\n                } catch (IllegalArgumentException e) {\n                    throw new IllegalArgumentException(\"Invalid messageId base64 value\", e);\n                }\n\n                try {\n                    messageId = MessageIdImpl.fromByteArray(decoded);\n                } catch (IOException | RuntimeException e) {\n                    throw new IllegalArgumentException(\"Invalid messageId value\", e);\n                }\n            }\n        }\n        return messageId;\n    }\n\n}\n","sourceCodeStart":381,"sourceCodeEnd":413,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/ReaderHandler.java#L381-L413","documentation":"ReaderHandler.getMessageId decodes the 'messageId' query parameter from Base64 before reconstructing a MessageIdImpl. When the parameter is not valid Base64, java.util.Base64 throws IllegalArgumentException and the handler rethrows it with the 'Invalid messageId base64 value' message. This happens before the more specific 'Invalid messageId value' check that validates the decoded bytes.","triggerScenarios":"GET /websocket/reader/<topic> with ?messageId=<value> where value contains characters outside the Base64 alphabet (spaces, '+', unencoded '/' or '='), e.g. a URL-unencoded or truncated message id.","commonSituations":"Not URL-encoding a raw message id that contains '+/=' characters; copying a message id from logs and truncating it; sending an empty or non-id string such as 'latest' misspelled.","solutions":["URL-encode the messageId parameter (Base64 '+' and '/' become %2B and %2F)","Verify the messageId string is complete and copied from the corresponding base64 encoding of the raw message id","Use the literal 'earliest' or 'latest' when you want boundary positions instead of a concrete id","Fix the message id at the source: read it from the received message's message-id field, not hand-crafted strings"],"exampleFix":"// before\nGET /websocket/reader/t/p?messageId=CgAAAA==\n// after\nGET /websocket/reader/t/p?messageId=CgAAAA%3D%3D","handlingStrategy":"validation","validationCode":"String safe = URLEncoder.encode(messageIdParam, StandardCharsets.UTF_8); if (messageIdParam.isEmpty() || !(messageIdParam.equals(\"earliest\") || messageIdParam.equals(\"latest\") || safe.equals(messageIdParam))) { throw new IllegalArgumentException(\"messageId must be earliest, latest, or URL-encoded base64\"); }","typeGuard":"boolean isUrlSafeBase64(String s) { return s.matches(\"[A-Za-z0-9+/=\\-%.]*\") && !s.isEmpty(); }","tryCatchPattern":"try { openReader(topic, messageIdParam); } catch (IllegalArgumentException e) { log.warn(\"bad messageId param: {}\", messageIdParam); openReader(topic, \"latest\"); }","preventionTips":["URL-encode query parameters, especially base64 (+, /, =)","Use the literal earliest/latest for boundary reads","Copy message ids from the SDK's base64 encoder, not manual transcription","Unit-test the reader URL builder with ids containing +/="],"tags":["websocket","base64","encoding","validation"],"backgroundTag":"invalid-base64-encoding","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}