apache/shardingsphere · error · FirebirdProtocolException

Unknown blob information request type

Error message

Unknown blob information request type %d

What it means

Thrown when a Firebird client requests blob information and the requested info item is not one of the four handled types (NUM_SEGMENTS, MAX_SEGMENT, TOTAL_LENGTH, TYPE). The Firebird protocol defines many isc_info_blob_* items; this implementation covers only the subset above, and any other item code hits the default branch and throws.

Solutions

  1. Identify the numeric item code in the message and map it to the isc_info_blob_* constant in Firebird's ibase.h
  2. Restrict client-side blob info requests to NUM_SEGMENTS, MAX_SEGMENT, TOTAL_LENGTH, and TYPE
  3. Contribute a handler for the missing item in FirebirdBlobInfoReturnPacket (write item code, 2-byte LE length, value) and raise it upstream
  4. As a workaround, fetch the blob stream directly instead of querying its info metadata

Example fix

// before: client requests an unimplemented blob info item
// (e.g. isc_info_blob_collation = 15)

// after: only request supported items
// int[] supported = { isc_info_blob_num_segments, isc_info_blob_max_segment,
//                     isc_info_blob_total_length, isc_info_blob_type };
Defensive patterns

Strategy: validation

Validate before calling

// before calling blob info, restrict to implemented items
private static final Set<Integer> SUPPORTED_BLOB_INFO = Set.of(
        FirebirdBlobInfoPacketType.NUM_SEGMENTS.getCode(),
        FirebirdBlobInfoPacketType.MAX_SEGMENT.getCode(),
        FirebirdBlobInfoPacketType.TOTAL_LENGTH.getCode(),
        FirebirdBlobInfoPacketType.TYPE.getCode());

int item = /* requested item */ 0;
if (!SUPPORTED_BLOB_INFO.contains(item)) {
    // degrade gracefully instead of triggering the throw
    return Optional.empty();
}

Type guard

static boolean isSupportedBlobInfoItem(final int code) {
    return code == FirebirdBlobInfoPacketType.NUM_SEGMENTS.getCode()
        || code == FirebirdBlobInfoPacketType.MAX_SEGMENT.getCode()
        || code == FirebirdBlobInfoPacketType.TOTAL_LENGTH.getCode()
        || code == FirebirdBlobInfoPacketType.TYPE.getCode();
}

Try / catch

try {
    packet.write(payload);
} catch (FirebirdProtocolException ex) {
    // unknown info item: respond with isc_info_error / skip the item rather than killing the session if your layer can
    log.warn("unsupported blob info item: {}", ex.getMessage());
}

Prevention

When it happens

Trigger: Calling isc_blob_info with items such as isc_info_blob_collation or any item beyond NUM_SEGMENTS/MAX_SEGMENT/TOTAL_LENGTH/TYPE, causing FirebirdBlobInfoReturnPacket.write() to fall into the default case.

Common situations: Using a Firebird client/driver feature (e.g. Jaybird's metadata calls) that queries blob info items this proxy does not implement yet; upgrading a client that newly requests extra items.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/fecb7ed81af7884d. Report an issue: GitHub.

Appendix: source

Thrown at database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/info/type/blob/FirebirdBlobInfoReturnPacket.java:71

            }
        }
        FirebirdCommonInfoPacketType.parseCommonInfo(payload, FirebirdCommonInfoPacketType.END);
    }
    
    private void parseBlobInfo(final FirebirdPacketPayload payload, final FirebirdBlobInfoPacketType type) {
        switch (type) {
            case NUM_SEGMENTS:
                writeIntValue(payload, type, getSegmentCount());
                return;
            case MAX_SEGMENT:
            case TOTAL_LENGTH:
                writeIntValue(payload, type, getSegmentLength());
                return;
            case TYPE:
                writeIntValue(payload, type, BLOB_TYPE_SEGMENTED);
                return;
            default:
                throw new FirebirdProtocolException("Unknown blob information request type %d", type.getCode());
        }
    }
    
    private void writeIntValue(final FirebirdPacketPayload payload, final FirebirdBlobInfoPacketType type, final int value) {
        payload.writeInt1(type.getCode());
        payload.writeInt2LE(4);
        payload.writeInt4LE(value);
    }
    
    private int getSegmentLength() {
        return blobLength;
    }
    
    private int getSegmentCount() {
        return 0 == blobLength ? 0 : 1;
    }
}

View on GitHub (pinned to e952770a21)