apache/iceberg · error · BadRequestException
Malformed request
Error message
Malformed request: %s
What it means
The NamespaceErrorHandler converts an HTTP 400 from the server into BadRequestException('Malformed request: %s') when the error type is not 'NamespaceNotEmptyException'. The library throws this when it cannot map the bad request to a more specific namespace exception, indicating the request body/parameters were rejected by the server as invalid.
Solutions
- Read the server-provided message after 'Malformed request:' - it names the specific validation the server rejected.
- Validate the namespace identifier format for the target catalog (allowed characters, level count, separator).
- Upgrade/align the iceberg-rest client version with the server's REST spec version if payloads changed.
- If the server meant 'namespace not empty' but did not set the type field, fix the server (or upgrade it) so it returns type NamespaceNotEmptyException.
Example fix
// before
String ns = "my/ns/with/slashes"; // server rejects
catalog.createNamespace(Namespace.of(ns));
// after
Namespace ns = Namespace.of("my_namespace");
catalog.createNamespace(ns); Defensive patterns
Strategy: validation
Validate before calling
Preconditions.checkArgument(ns.levels().length > 0 && ns.levels()[0].matches("[A-Za-z0-9_-]+"), "invalid namespace"); Try / catch
catch (BadRequestException e) { log.error("Server rejected request: {}", e.getMessage()); /* fix request, do not retry */ } Prevention
- Validate namespace identifier characters and hierarchy client-side
- Keep iceberg client and REST server versions spec-compatible
- Never auto-retry 400 responses - fix the request payload instead
When it happens
Trigger: Namespace REST calls (createNamespace, setProperties, removeProperties, listNamespaces) where the server responds 400 with an ErrorResponse whose type field is null or unrecognized - e.g. invalid namespace syntax in the request, malformed JSON payload, unsupported properties payload.
Common situations: Namespace names containing characters the server rejects; sending multi-level namespaces to a catalog expecting a different separator; client/server spec version skew causing schema mismatches; hand-crafted REST requests with invalid bodies.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid snapshot mode
- Namespace does not exist
- Can not alter the default database when the iceberg catalog…
- Cannot apply unknown namespace change
- Cannot apply unknown namespace change
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/0c49a35801232262.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/rest/ErrorHandlers.java:276
throw new AlreadyExistsException("%s", error.message());
}
super.accept(error);
}
}
/** Request error handler specifically for create-read-update ops on namespaces. */
private static class NamespaceErrorHandler extends DefaultErrorHandler {
private static final ErrorHandler INSTANCE = new NamespaceErrorHandler();
@Override
public void accept(ErrorResponse error) {
switch (error.code()) {
case 400:
if (NamespaceNotEmptyException.class.getSimpleName().equals(error.type())) {
throw new NamespaceNotEmptyException("%s", error.message());
}
throw new BadRequestException("Malformed request: %s", error.message());
case 404:
throw new NoSuchNamespaceException("%s", error.message());
case 409:
throw new AlreadyExistsException("%s", error.message());
case 422:
throw createRESTException(error);
}
super.accept(error);
}
}
/** Request error handler for drop namespace operations. */
private static class DropNamespaceErrorHandler extends NamespaceErrorHandler {
private static final ErrorHandler INSTANCE = new DropNamespaceErrorHandler();
@Override
public void accept(ErrorResponse error) {View on GitHub (pinned to 86d9c8fc54)