{"record":{"id":"e3968902d5de3c57","repo":"apache/iceberg","slug":"malformed-json-s","errorCode":null,"errorMessage":"Malformed JSON: %s","messagePattern":"Malformed JSON: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"snowflake/src/main/java/org/apache/iceberg/snowflake/SnowflakeTableMetadata.java","lineNumber":139,"sourceCode":"      // gcs://bucket/path\n      // to:\n      // gs://bucket/path\n      return \"gs\" + snowflakeLocation.substring(3);\n    }\n\n    return snowflakeLocation;\n  }\n\n  /**\n   * Factory method for parsing a JSON string containing expected Snowflake table metadata into a\n   * SnowflakeTableMetadata object.\n   */\n  public static SnowflakeTableMetadata parseJson(String json) {\n    JsonNode parsedVal;\n    try {\n      parsedVal = JsonUtil.mapper().readValue(json, JsonNode.class);\n    } catch (IOException ioe) {\n      throw new IllegalArgumentException(String.format(\"Malformed JSON: %s\", json), ioe);\n    }\n\n    String snowflakeMetadataLocation = JsonUtil.getString(\"metadataLocation\", parsedVal);\n    String status = JsonUtil.getStringOrNull(\"status\", parsedVal);\n\n    String icebergMetadataLocation = snowflakeLocationToIcebergLocation(snowflakeMetadataLocation);\n\n    return new SnowflakeTableMetadata(\n        snowflakeMetadataLocation, icebergMetadataLocation, status, json);\n  }\n}\n","sourceCodeStart":121,"sourceCodeEnd":151,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/snowflake/src/main/java/org/apache/iceberg/snowflake/SnowflakeTableMetadata.java#L121-L151","documentation":"SnowflakeTableMetadata.parseJson wraps IOExceptions from Jackson when parsing the metadata JSON string returned by the Snowflake client into IllegalArgumentException with 'Malformed JSON'. This payload comes from Snowflake's GET (system) GET_ICEBERG_TABLE_INFO/metadata API, so a non-JSON response indicates a client/protocol problem rather than bad user data.","triggerScenarios":"snowflakeClient.loadTableMetadata returns a string that is not valid JSON (empty string, HTML error page, truncated response, driver-level error text), which readValue fails to parse.","commonSituations":"Expired or misconfigured Snowflake session returning an error body instead of JSON; older Snowflake JDBC/driver versions returning a different payload shape; network proxies or Snowflake outages injecting non-JSON error pages; programmatic misuse of parseJson with hand-built strings.","solutions":["Verify Snowflake connectivity and credentials; an error page or empty body usually means auth/session failure upstream of this parse.","Upgrade the Snowflake JDBC driver and iceberg-snowflake module to matched recent versions so the metadata payload shape is supported.","Log the raw JSON string from the exception message and inspect it — it reveals what the client actually received (HTML vs truncated JSON).","Retry the load; transient Snowflake API failures can produce malformed bodies. Add retry with backoff around loadTableMetadata."],"exampleFix":"// before\nSnowflakeTableMetadata meta = SnowflakeTableMetadata.parseJson(client.loadTableMetadata(id));\n// after\nString json = client.loadTableMetadata(id);\nif (json == null || !json.trim().startsWith(\"{\")) {\n  throw new IllegalStateException(\"Unexpected Snowflake metadata payload: \" + json);\n}\nSnowflakeTableMetadata meta = SnowflakeTableMetadata.parseJson(json);","handlingStrategy":"try-catch","validationCode":"if (json == null || json.trim().isEmpty() || !(json.trim().startsWith(\"{\") || json.trim().startsWith(\"[\"))) {\n  throw new IllegalStateException(\"Snowflake metadata payload is not JSON: \" + json);\n}","typeGuard":null,"tryCatchPattern":"try { meta = SnowflakeTableMetadata.parseJson(json); } catch (IllegalArgumentException e) { LOG.error(\"Bad Snowflake metadata payload: {}\", json, e); throw new RetryableLoadException(e); }","preventionTips":["Keep Snowflake JDBC driver and iceberg-snowflake versions current","Verify Snowflake auth/session health when metadata loads start failing","Retry transient loads with backoff; log the raw payload for diagnosis"],"tags":["json","parse-error","snowflake"],"backgroundTag":"json-parse-error","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}