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

  1. Read the server-provided message after 'Malformed request:' - it names the specific validation the server rejected.
  2. Validate the namespace identifier format for the target catalog (allowed characters, level count, separator).
  3. Upgrade/align the iceberg-rest client version with the server's REST spec version if payloads changed.
  4. 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

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.

Related errors


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)