{"record":{"id":"59c1f972aee056d4","repo":"flowable/flowable-engine","slug":"header-name-cannot-be-null-or-empty","errorCode":null,"errorMessage":"header name cannot be null or empty","messagePattern":"header name cannot be null or empty","errorType":"validation","errorClass":"FlowableMailException","httpStatus":null,"severity":"error","filePath":"modules/flowable-mail/src/main/java/org/flowable/mail/common/impl/jakarta/mail/JakartaMailFlowableMailClient.java","lineNumber":151,"sourceCode":"    protected void setSubject(MimeMessage message, String subject, Charset charset) throws MessagingException {\n        if (StringUtils.isNotEmpty(subject)) {\n            if (charset != null) {\n                message.setSubject(subject, charset.name());\n            } else {\n                message.setSubject(subject);\n            }\n        }\n    }\n\n    protected void addHeaders(MimeMessage message, Map<String, String> headers, Charset charset) throws MessagingException {\n        if (headers != null && !headers.isEmpty()) {\n            for (Map.Entry<String, String> entry : headers.entrySet()) {\n\n                String name = entry.getKey();\n                String value = entry.getValue();\n\n                if (StringUtils.isEmpty(name)) {\n                    throw new FlowableMailException(\"header name cannot be null or empty\");\n                }\n\n                if (StringUtils.isEmpty(value)) {\n                    throw new FlowableMailException(\"header value cannot be null or empty\");\n                }\n\n                String foldedHeaderValue = createFoldedHeaderValue(name, value, charset);\n                message.addHeader(name, foldedHeaderValue);\n            }\n        }\n\n    }\n\n    protected String createFoldedHeaderValue(String name, String value, Charset charset) {\n        try {\n            return MimeUtility.fold(name.length() + 2, MimeUtility.encodeText(value, charset != null ? charset.name() : null, null));\n        } catch (UnsupportedEncodingException e) {\n            return value;","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-mail/src/main/java/org/flowable/mail/common/impl/jakarta/mail/JakartaMailFlowableMailClient.java#L133-L169","documentation":"When building the MimeMessage, addHeaders iterates the request's custom headers map and rejects any entry whose key is null or empty, throwing FlowableMailException. RFC 822 messages cannot have a header without a name, so the client fails fast instead of producing a corrupt message.","triggerScenarios":"Passing a SendMailRequest whose extraHeaders map contains an empty-string or null key, e.g. headers built programmatically from name/value pairs where the name part was missing.","commonSituations":"Dynamic header construction from CSV/database rows with blank column names; parsing 'Name: Value' strings with a split that yields an empty name; deserialization of user-supplied header maps.","solutions":["Filter out entries with null/empty keys from the headers map before building the SendMailRequest.","Fix the upstream data source so header names are always present and trimmed.","Add application-level validation of the headers map before invoking the mail client."],"exampleFix":"// before\nMap<String,String> headers = parseHeaders(input); // may contain \"\"\nSendMailRequest req = SendMailRequest.builder().extraHeaders(headers).build();\n\n// after\nMap<String,String> headers = parseHeaders(input).entrySet().stream()\n    .filter(e -> e.getKey() != null && !e.getKey().isBlank())\n    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));","handlingStrategy":"validation","validationCode":"Map<String,String> safeHeaders = headers.entrySet().stream()\n    .filter(e -> e.getKey() != null && !e.getKey().trim().isEmpty())\n    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));","typeGuard":"boolean hasNamedHeaders(Map<String,String> h) { return h.keySet().stream().allMatch(k -> k != null && !k.isBlank()); }","tryCatchPattern":"try { client.sendMail(request); } catch (FlowableMailException e) { if (e.getMessage().contains(\"header name\")) { log.warn(\"dropping request with unnamed header\"); } throw e; }","preventionTips":["Trim and validate header names when building them from external data.","Reject empty header names at the parse/ingestion layer.","Add unit tests covering blank header names."],"tags":["mail","headers","validation","jakarta-mail"],"backgroundTag":"empty-required-field","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}