{"record":{"id":"12064e3a04aa5602","repo":"apache/iceberg","slug":"cannot-write-null-to-required-string-column","errorCode":null,"errorMessage":"Cannot write null to required string column","messagePattern":"Cannot write null to required string column","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/avro/ValueWriters.java","lineNumber":251,"sourceCode":"    }\n  }\n\n  private static class StringWriter implements ValueWriter<Object> {\n    private static final StringWriter INSTANCE = new StringWriter();\n\n    private StringWriter() {}\n\n    @Override\n    public void write(Object s, Encoder encoder) throws IOException {\n      // use getBytes because it may return the backing byte array if available.\n      // otherwise, it copies to a new byte array, which is still cheaper than Avro\n      // calling toString, which incurs encoding costs\n      if (s instanceof Utf8) {\n        encoder.writeString((Utf8) s);\n      } else if (s instanceof String) {\n        encoder.writeString(new Utf8((String) s));\n      } else if (s == null) {\n        throw new IllegalArgumentException(\"Cannot write null to required string column\");\n      } else {\n        throw new IllegalArgumentException(\n            \"Cannot write unknown string type: \" + s.getClass().getName() + \": \" + s);\n      }\n    }\n  }\n\n  private static class Utf8Writer implements ValueWriter<Utf8> {\n    private static final Utf8Writer INSTANCE = new Utf8Writer();\n\n    private Utf8Writer() {}\n\n    @Override\n    public void write(Utf8 s, Encoder encoder) throws IOException {\n      encoder.writeString(s);\n    }\n  }\n","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/avro/ValueWriters.java#L233-L269","documentation":"The string ValueWriter in ValueWriters writes Utf8 or String values into a required (non-nullable) column; when the value is null, it cannot be encoded, so this IllegalArgumentException is thrown. Nulls require an optional column or a writer that handles nulls.","triggerScenarios":"Writing a record where a String field mapped to a required column carries null; using ValuesWriter with a non-nullable schema but supplying null values.","commonSituations":"Mismatch between nullable data source and Iceberg required column; missing default/coalesce logic in the ETL before writing.","solutions":["Coerce nulls before writing (default value, empty string, or drop the row)","Make the column optional in the table schema so null is a valid value","Ensure the writer used matches nullability (a nullable writer wraps with option writer)"],"exampleFix":"// before\nString val = maybeNull();\nwriter.write(val, encoder);\n// after\nwriter.write(val == null ? \"\" : val, encoder);","handlingStrategy":"validation","validationCode":"if (value == null && column.isRequired()) throw new IllegalArgumentException(\"null for required string column: \" + column.name());","typeGuard":"String requireNonNullString(String s) { return Objects.requireNonNull(s, \"required string value is null\"); }","tryCatchPattern":"try { writer.writeValue(encoder, s); } catch (IllegalArgumentException e) { if (e.getMessage().equals(\"Cannot write null to required string column\")) { /* default value or make column optional */ } else throw e; }","preventionTips":["Coalesce nulls to defaults before writing","Declare columns optional when the source allows nulls","Unit-test writers with null inputs per column"],"tags":["avro","null-value","write"],"backgroundTag":"null-argument","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}