{"id":"9d0fa0e856b81ce7","repo":"apache/kafka","slug":"string-may-not-contain-control-sequences-but-had-t","errorCode":null,"errorMessage":"String may not contain control sequences but had the following ASCII chars: foundIllegalCharacters.stream().map(Object::toString).collect(Collectors.joining(\", \"))","messagePattern":"String may not contain control sequences but had the following ASCII chars: foundIllegalCharacters\\.stream\\(\\)\\.map\\(Object::toString\\)\\.collect\\(Collectors\\.joining\\(\", \"\\)\\)","errorType":"validation","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java","lineNumber":1270,"sourceCode":"                // This can happen during creation of the config object due to no default value being defined for the\n                // name configuration - a missing name parameter is caught when checking for mandatory parameters,\n                // thus we can ok a null value here\n                return;\n            } else if (s.isEmpty()) {\n                throw new ConfigException(name, value, \"String may not be empty\");\n            }\n\n            // Check name string for illegal characters\n            ArrayList<Integer> foundIllegalCharacters = new ArrayList<>();\n\n            for (int i = 0; i < s.length(); i++) {\n                if (Character.isISOControl(s.codePointAt(i))) {\n                    foundIllegalCharacters.add(s.codePointAt(i));\n                }\n            }\n\n            if (!foundIllegalCharacters.isEmpty()) {\n                throw new ConfigException(name, value, \"String may not contain control sequences but had the following ASCII chars: \" +\n                        foundIllegalCharacters.stream().map(Object::toString).collect(Collectors.joining(\", \")));\n            }\n        }\n\n        public String toString() {\n            return \"non-empty string without ISO control characters\";\n        }\n    }\n\n    public static class ListSize implements Validator {\n        final int maxSize;\n\n        private ListSize(final int maxSize) {\n            this.maxSize = maxSize;\n        }\n\n        public static ListSize atMostOfSize(final int maxSize) {\n            return new ListSize(maxSize);","sourceCodeStart":1252,"sourceCodeEnd":1288,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java#L1252-L1288","documentation":"Thrown by NonEmptyStringWithoutControlChars.ensureValid after scanning every code point of the value with Character.isISOControl and collecting any control characters (e.g. NUL \\u0000, BEL \\u0007, newline \\n, tab \\t, escape \\u001b, DEL \\u007F). The message lists the decimal ASCII/Unicode code points of the offending characters. Kafka rejects these because identifier/name fields flow into protocol payloads, log lines, and JSON where control chars cause corruption or parsing failures.","triggerScenarios":"A ConfigKey validated with NonEmptyStringWithoutControlChars is supplied a string containing at least one ISO control character. Triggered during ConfigDef.parse() once the empty-string check has passed. The offending characters are typically invisible in editors and logs, hence the numeric reporting.","commonSituations":"Copy-pasting values from rich-text editors or spreadsheets that embed formatting control chars; values sourced from secrets managers that include a trailing newline; shell commands that inject tabs or escapes; malformed multi-line properties where a continuation line break lands inside a value.","solutions":["Strip control characters from the value before assigning: value.replaceAll(\"\\\\p{Cntrl}\", \"\").","Re-enter the value by hand in a plain-text editor to remove hidden characters copied from rich text or spreadsheets.","If the value comes from a secret/env var, trim trailing newlines: value.stripTrailing() or strip().","Inspect the value with a hex dump (od -c, xxd) to locate the exact code points and their source."],"exampleFix":"// before\n// listener name copied from a spreadsheet, contains a trailing \\u0007 (BEL)\nprops.put(\"advertised.listeners\", \"PLAINTEXT://host:9092\\u0007\");\n\n// after\n// sanitize or re-enter cleanly\nString raw = envOrSecretValue().strip().replaceAll(\"\\\\p{Cntrl}\", \"\");\nprops.put(\"advertised.listeners\", raw);","handlingStrategy":"validation","validationCode":"// Reject ISO control characters before Kafka sees the value:\nString k = \"group.id\";\nString v = (String) props.get(k);\nif (v != null) {\n    for (int i = 0; i < v.length(); i++) {\n        if (Character.isISOControl(v.codePointAt(i))) {\n            throw new IllegalArgumentException(k + \" contains control char U+\" + Integer.toHexString(v.codePointAt(i)));\n        }\n    }\n}\n// Or sanitize: v = v.replaceAll(\"\\\\p{Cc}\", \"\");","typeGuard":"// A small value type that guarantees control-char-free strings:\nstatic final class CleanStr {\n    final String value;\n    CleanStr(String v) {\n        if (v != null) for (int i = 0; i < v.length(); i++)\n            if (Character.isISOControl(v.codePointAt(i)))\n                throw new IllegalArgumentException(\"control char at \" + i);\n        this.value = v;\n    }\n}","tryCatchPattern":"try {\n    def.parse(props);\n} catch (ConfigException ce) {\n    if (ce.getMessage().startsWith(\"String may not contain control sequences\")) {\n        // Strip control chars and retry once\n        String cleaned = ((String) ce.value()).replaceAll(\"\\\\p{Cc}\", \"\");\n        props.put(ce.getName(), cleaned);\n    } else throw ce;\n}","preventionTips":["Sanitize any value sourced from a Properties file or env var with replaceAll(\"\\\\p{Cc}\", \"\") if control chars are plausible.","Reject copy-pasted identifiers that contain tabs/newlines (common from spreadsheets).","Log the offending code points (ce.getMessage() lists them) so the source is easy to locate."],"tags":["config","kafka-client","validation","validator","control-characters","sanitization"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}