{"id":"e11ee3798e3c1202","repo":"apache/kafka","slug":"client-rack-must-be-provided-if-partitioner-rack-a","errorCode":null,"errorMessage":"client.rack must be provided if partitioner.rack.aware is enabled","messagePattern":"client\\.rack must be provided if partitioner\\.rack\\.aware is enabled","errorType":"validation","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/producer/internals/RecordAccumulator.java","lineNumber":1283,"sourceCode":"        /**\n         * Partitioner config\n         *\n         * @param enableAdaptivePartitioning If it's true, partition switching adapts to broker load, otherwise partition\n         *        switching is random.\n         * @param partitionAvailabilityTimeoutMs If a broker cannot process produce requests from a partition\n         *        for the specified time, the partition is treated by the partitioner as not available.\n         *        If the timeout is 0, this logic is disabled.\n         * @param rackAware Whether the built-in partitioner is configured to be rack-aware.\n         * @param rack The producer rack.\n         */\n        public PartitionerConfig(boolean enableAdaptivePartitioning, long partitionAvailabilityTimeoutMs, boolean rackAware, String rack) {\n            this.enableAdaptivePartitioning = enableAdaptivePartitioning;\n            this.partitionAvailabilityTimeoutMs = partitionAvailabilityTimeoutMs;\n            this.rackAware = rackAware;\n            this.rack = rack;\n\n            if (rackAware && Utils.isBlank(rack)) {\n                throw new ConfigException(\"client.rack must be provided if partitioner.rack.aware is enabled\");\n            }\n        }\n\n        public PartitionerConfig() {\n            this(false, 0, false, \"\");\n        }\n    }\n\n    /*\n     * Result of an attempt to append a record to the accumulator. Carries exactly one of three\n     * mutually-exclusive outcomes: the record was appended ({@link RecordAppendResult#appended()}, {@code future} is set),\n     * the open batch needs more chunk capacity first ({@link RecordAppendResult#needsBufferExtension()}),\n     * or a new batch must be created for the record ({@link RecordAppendResult#needsNewBatch()}).\n     */\n    public static final class RecordAppendResult {\n        /**\n         * The three mutually-exclusive outcomes of an append attempt. Internal representation only;\n         * callers use {@link #appended()}, {@link #needsBufferExtension()}, and {@link #needsNewBatch()}.","sourceCodeStart":1265,"sourceCodeEnd":1301,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/producer/internals/RecordAccumulator.java#L1265-L1301","documentation":"Thrown by RecordAccumulator.PartitionerConfig's constructor when partitioner.rack.aware=true but the producer's client.rack is null or blank. Rack-aware partitioning requires a producer rack so the built-in partitioner can prefer a leader replica in the same rack; without one the constraint cannot be honoured, so construction fails fast at producer init rather than silently degrading.","triggerScenarios":"Configuring partitioner.rack.aware=true (or partitioner.class that delegates rack-aware behaviour to the built-in) without also setting client.rack. The ConfigException is raised during KafkaProducer construction when the PartitionerConfig is built.","commonSituations":"Copied config from a broker or another client that had client.rack set; deployment into a new region/AZ where client.rack was not templated; enable rack-awareness for cross-AZ bandwidth savings but forget the matching client.rack; environment-variable-driven config where CLIENT_RACK was unset.","solutions":["Set client.rack to a non-blank value (typically the AZ/zone, e.g. \"us-east-1a\") whenever partitioner.rack.aware=true.","Or, if rack-awareness is not actually wanted, set partitioner.rack.aware=false (the default).","Drive client.rack from the deployment environment (e.g. AWS availability-zone via instance metadata) so it is never blank.","Validate required config pairs at application startup so the failure is logged with context before the producer is constructed."],"exampleFix":"// before\nprops.put(\"partitioner.rack.aware\", \"true\");\n// client.rack omitted -> ConfigException\n\n// after\nprops.put(\"partitioner.rack.aware\", \"true\");\nprops.put(\"client.rack\", System.getenv(\"AZ\")); // e.g. \"us-east-1a\"","handlingStrategy":"validation","validationCode":"String rack = configs.get(\"client.rack\") == null ? null : String.valueOf(configs.get(\"client.rack\")).trim();\nboolean rackAware = Boolean.parseBoolean(String.valueOf(configs.getOrDefault(\"partitioner.rack.aware\", \"false\")));\nif (rackAware && rack == null || rack != null && rack.isEmpty()) {\n    throw new IllegalArgumentException(\"client.rack must be set when partitioner.rack.aware=true\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    producer = new KafkaProducer<>(configs);\n} catch (org.apache.kafka.common.config.ConfigException ce) {\n    // log, abort startup, and fix configuration before retrying\n}","preventionTips":["Treat client.rack and partitioner.rack.aware as a coupled pair in config validation.","Source client.rack from deployment metadata (availability zone, node label) rather than hardcoding.","Validate the full producer config at startup and fail fast before constructing KafkaProducer."],"tags":["producer","config","partitioner","rack-aware","java"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}