Migrating from Apicurio Registry 2.6.3 to Apicurio Registry 3.x

This documentation describes how to migrate from Apicurio Registry 2.6.3 to Apicurio Registry 3.x.

Apicurio Registry 3.x includes breaking changes that require a new deployment, data migration, and client application updates. There is no in-place upgrade path from v2 to v3.

Changes in Apicurio Registry 3.x

Apicurio Registry 3.x includes a redesigned data model, a reworked REST API, and a refreshed SDK ecosystem compared to Apicurio Registry 2.6.3.

Because of the breaking changes in 3.x, there is no in-place upgrade. You must deploy a new 3.x instance, migrate the persisted content, and update your client applications and automation.

When migrating to version 3.x, consider the following changes:

Updated data model and governance

Apicurio Registry 3.x separates artifact metadata from version metadata and introduces first-class support for empty artifacts (artifacts without versions). These capabilities enable you to prepare governance metadata, rules, and branch structures before adding the first version. Additional highlights include:

  • Artifact metadata is now managed independently from version metadata.

  • Groups and artifacts can define custom labels to improve categorization.

  • Create and manage custom branches. The system manages the latest branch automatically.

Core v3 REST API

The v3 REST API focuses on consistency and discoverability:

  • Group management covers descriptions, owners, labels, and hierarchical rules.

  • New search endpoints at /search/groups and /search/versions expand discovery.

  • Version-focused endpoints streamline content management and require explicit Content-Type headers.

  • A dryRun query parameter on artifact and version creation endpoints replaces the former /test endpoints. When dryRun=true, the API validates the request and returns a response without committing changes.

  • A dedicated Branch API enables multitrack artifact development.

Re-engineered Kafka storage

The KafkaSQL storage implementation is optimized for stability and maintainability. The new design reduces startup times for large installations.

Architectural changes in v3

The KafkaSQL storage uses a true event journaling pattern that requires a different Kafka topic than v2, with different configuration settings. The v3 journal format is incompatible with v2.

Separate UI container

The user interface is now deployed as a separate container, providing more deployment flexibility and independent scaling of UI and API components.

Generated SDKs powered by Kiota

Apicurio Registry 3.x ships Kiota-generated SDKs that mirror the REST API structure across languages. Updated libraries are available for Java, TypeScript, Python, and Go, providing lightweight, type-safe clients with minimal dependencies and consistent naming.

Migration planning

Select the migration approach that best aligns with your architecture, and customize the steps for your infrastructure.

Feature Minimal downtime migration Maintenance window migration

Primary Method

Parallel environments with reverse proxy or load balancer routing

Sequential process

Complexity

High: Requires configuration for dual-routing and traffic management.

Low: Straightforward, linear execution steps.

Read Downtime

10-30 seconds (Switchover latency)

1-2 hours (Full duration of maintenance)

Write Downtime

30-45 minutes (Final sync and import phase)

1-2 hours (Full duration of maintenance)

Infrastructure

Requires Nginx or HAProxy and running dual instances.

Single target environment.

Best For

High-availability production environments.

Development, staging, or systems with flexible SLAs.

Regardless of the migration path you choose, you need to:

  • Test the data migration in a staging environment before migrating production. A dry run helps you estimate timing for export and import phases. See Migrating Apicurio Registry data.

  • Verify client applications connect to Apicurio Registry 3.x after the data migration completes. For minimal downtime migrations, verify the load balancer routes to 3.x and update any clients that bypass the load balancer. For maintenance window migrations, update client configurations directly. See Migrating Apicurio Registry client applications.

  • Update configuration properties for the v3 deployment. Combine this with client updates where possible. See Updating Apicurio Registry configuration.

Minimal downtime migration

The objective is to keep the service reachable. While data is being moved, a reverse proxy (such as nginx) manages the cutover. See Migrating with minimal downtime.

Maintenance window migration

This approach ensures the cleanest data integrity. By stopping all client applications first, you ensure no data is in flight during the move. See Migrating in a maintenance window.

During a minimal downtime migration, you temporarily run both Apicurio Registry 2.6.3 and Apicurio Registry 3.x simultaneously. Plan for:

Infrastructure:

  • Separate database instances for v2 and v3 (or different schemas in the same database)

  • For KafkaSQL deployments: same Kafka cluster with different topic names

  • Load balancer capacity for routing traffic

  • Network connectivity between all components

Storage requirements:

  • v2 database/storage: existing size

  • v3 database/storage: approximately same size as v2 (plan for 110% of the v2 size)

  • Export file storage: approximately 10-20% of the database size (compressed)

Timeline:

  • Keep v2 running for 1-7 days after migration for rollback capability

  • Total parallel operation period: 1-7 days

  • Budget for staging environment testing before production migration

Prerequisites

Before beginning migration:

Requirement Description

Staging environment

Test complete migration workflow before production

Load balancer

nginx, HAProxy, or similar for traffic management

Administrative access

Admin role credentials for export/import API endpoints and testing admin functionality

Database or storage

Separate database instance or schema (or separate Kafka topic) for Apicurio Registry 3.x

Backup

Current backup of 2.6.3 data

Rollback plan

Documented procedure to revert to v2 if needed

Migrating with minimal downtime

Follow this phase-based workflow to migrate from Apicurio Registry 2.6.3 to 3.x with minimal downtime. Each phase includes steps and validation checkpoints.

Understanding the workflow

The minimal downtime migration approach uses a load balancer to manage traffic routing. This minimizes read-operation downtime and controls write operations during data export.

┌────────────────────────────────────────────────────────────────┐
│                     Client Applications                        │
└───────────────────────────┬────────────────────────────────────┘
                            │
                            ↓
                    ┌───────────────┐
                    │ Load Balancer │  (such as nginx or HAProxy)
                    └───────┬───────┘
                            │
        ┌───────────────────┼───────────────────┐
        │                   │                   │
        ↓                   ↓                   ↓
┌───────────────┐   ┌───────────────┐   ┌───────────────┐
│  Registry 2.x │   │  Registry 2.x │   │  Registry 3.x │
│   + Storage   │   │   + Storage   │   │   + Storage   │
└───────────────┘   └───────────────┘   └───────────────┘
    (read/write)        (read-only)         (read/write)
Test as much of the migration as possible in a staging environment before migrating in production.
Phase 1: Preparation
  1. Deploy load balancer

    If not already using a load balancer, deploy nginx or HAProxy in front of your existing 2.6.3 deployment:

    1. Deploy load balancer

    2. Configure to route traffic to 2.6.3

    3. Update client applications to connect through load balancer

    4. Validate all traffic flows correctly

    See Updating registry configuration for load balancer configuration examples.

  2. Prepare Apicurio Registry 3.x infrastructure

    Deploy the infrastructure for Apicurio Registry 3.x without starting the registry application:

    • For SQL storage: Deploy a separate database instance or create a separate schema

    • For KafkaSQL storage: Use the same Kafka cluster but configure a different topic name

    • Prepare TLS certificates (can reuse 2.6.3 certificates)

    • Configure the OAuth2/OIDC authentication provider

    See Updating registry configuration for detailed configuration changes.

    Checkpoint: v2 traffic flowing through load balancer, v3 infrastructure ready.

Phase 2: Pre-migration validation
  1. Enable read-only mode

    Configure the load balancer to block write operations while allowing read operations. This prevents data changes during export.

    Update your load balancer configuration to block POST, PUT, PATCH, and DELETE methods:

    # nginx read-only configuration
    server {
        location / {
            if ($request_method !~ ^(GET|HEAD|OPTIONS)$) {
                return 405 "Registry temporarily in read-only mode for migration";
            }
            proxy_pass http://registry-v2:8080;
        }
    }

    Reload the load balancer configuration and verify that read-only mode works correctly.

    Impact: Read operations (schema lookups) continue normally. Write operations (new schemas, updates) return HTTP 405. Kafka producers with auto-registration enabled cannot register new schemas.

  2. Capture baseline metrics

    Record the current state of your 2.6.3 deployment for comparison after migration.

    For the metrics capture procedure, see Migration scripts reference.

    Checkpoint: Read-only mode active, write operations blocked. Baseline documented, ready for data migration.

Phase 3: Data migration
  1. Export data from 2.6.3

    Export all artifacts, versions, metadata, and rules from 2.6.3 while the registry is in read-only mode.

    For the export procedure, see Migrating Apicurio Registry data.

    Access the registry directly (not through the load balancer) to bypass read-only restrictions on admin endpoints if needed.

    Checkpoint: Export complete, data snapshot captured.

  2. Deploy Apicurio Registry 3.x

    Deploy Apicurio Registry 3.x using the infrastructure prepared in Step 2. Configure the v3 deployment similarly to the previous v2 deployment. Note that various configuration parameters are renamed or changed.

    See Updating registry configuration for v3 configuration information and examples.

    Checkpoint: Apicurio Registry 3.x deployed and healthy (empty, awaiting import).

  3. Import data into Apicurio Registry 3.x

    Import the exported ZIP archive into the 3.x deployment.

    For the import procedure, see Migrating Apicurio Registry data.

    The import adds to existing data and does not replace it. For best results, import into an empty v3 registry.

    Checkpoint: Import complete, ready for validation.

  4. Validate import

    Verify the Apicurio Registry 3.x deployment and confirm that the data migration succeeded.

    For the validation procedure, see Migrating Apicurio Registry data.

    If validation fails, investigate import logs and retry if necessary. Do not proceed to traffic switch until all checks pass.

    Checkpoint: v3 has all data, data metrics match v2, ready for traffic switch.

Phase 4: Traffic switch
  1. Switch load balancer to Apicurio Registry 3.x

    Update the load balancer configuration to route to Apicurio Registry 3.x and enable read/write operations. The following example shows an nginx configuration:

    # nginx v3 configuration (read/write enabled)
    upstream registry {
        server registry-v3:8080;
    }
    
    server {
        location / {
            # All methods allowed
            proxy_pass http://registry;
            proxy_set_header Host $host;
        }
    }

    Reload the load balancer.

    Service Interruption: This operation may cause 10-30 seconds of brief service interruption during the reload. If your load balancer supports graceful reloads (for example, nginx -s reload), the interruption may be minimal.

    Checkpoint: All traffic routed to v3, write operations resumed.

  2. Verify traffic to the v3 deployment

    Confirm traffic is flowing to Apicurio Registry 3.x through the load balancer. Verify the registry is accessible, version is 3.x, health checks pass, and write operations are enabled.

    For the verification procedure, see Migration scripts reference.

    Checkpoint: Confirmed v3 is accessible and write operations working, no errors in logs.

Phase 5: Post-migration validation
  1. Test v2 API backward compatibility

    Verify that existing v2 clients can access the 3.x registry through the v2 API compatibility layer.

    For backward compatibility details and client migration guidance, see Migrating Apicurio Registry client applications.

    Checkpoint: v2 clients work correctly against v3 registry.

  2. Test v3 Core API functionality

    Verify v3-specific API features work correctly, including system endpoints, search endpoints, admin endpoints, and the Branch API.

    For the v3 API verification procedure, see Migration scripts reference.

    Checkpoint: v3 Core API features working correctly.

  3. Run smoke tests

    Execute production smoke tests to validate critical functionality:

    1. Test critical client applications

    2. Verify Kafka SerDes applications work (if applicable)

    3. Check authentication and authorization

    4. Monitor error rates and performance metrics

    5. Validate no increase in 4xx/5xx errors

    Checkpoint: All smoke tests passed, production traffic stable.

Phase 6: Stabilization
  1. Monitor and observe

    Keep 2.6.3 running but not serving traffic for rollback capability:

    • Monitor Apicurio Registry 3.x for 24-48 hours minimum

    • Watch for error rates, performance issues, or unexpected behavior

    • Prepare for immediate rollback if critical issues arise (switch load balancer back to v2)

    • Begin planning gradual client application migration to v3 SDKs

    See Migrating registry client applications for guidance on updating client applications.

    Checkpoint: v3 stable for 1-7 days, no rollback needed.

  1. Decommission 2.6.3

    After 1-7 days of successful operation on Apicurio Registry 3.x, decommission v2 infrastructure.

    Update documentation to reflect v3 as the production registry.

    Checkpoint: Migration complete, v2 decommissioned.

Rolling back to 2.6.3

A key advantage of the parallel deployment (minimal downtime migration) approach is the ability to quickly roll back if issues arise.

Scenario Description Considerations

Immediate rollback (within hours of migration)

  • Switch load balancer traffic back to 2.6.3.

  • Investigate issues with the 3.x deployment.

  • Recovery time: 30–60 seconds.

  • Minimal operational impact.

Delayed rollback (days after migration)

  • Assess data created in 3.x since migration.

  • Decide on rollback approach.

  • Options include:

    • Accepting data loss and rolling back to v2.

    • Fixing issues and remaining on v3 (preferred).

Preventing rollback scenarios

  • Test the migration thoroughly in a staging environment.

  • Validate data integrity before switching production traffic.

  • Run comprehensive smoke tests after migration.

Reduces the likelihood of rollback being required.

Migrating within a maintenance window

For environments where downtime is acceptable, follow this simpler sequential process.

Prerequisites

Perform a dry run migration in a staging environment to estimate the timing of the data export and import phases accurately. Once you are satisfied with the results, proceed with the production migration.

Procedure
  1. Stop all client applications that connect to Apicurio Registry 2.6.3.

  2. Export data from Apicurio Registry 2.6.3 using the export script. See Migration scripts reference.

  3. Shut down Apicurio Registry 2.6.3.

  4. Deploy Apicurio Registry 3.x with updated configuration. See Updating registry configuration.

  5. Import data into Apicurio Registry 3.x using the import script. See Migration scripts reference.

  6. Validate the import using the verification scripts. See Migration scripts reference.

  7. Update client application configurations to point to Apicurio Registry 3.x. See Migrating Apicurio Registry client applications.

  8. Start client applications.

Troubleshooting migration issues

If you encounter issues during migration, use the following guidance.

Export fails:

  • Check the authentication credentials are valid

  • Verify 2.6.3 is accessible

  • Review registry logs for errors

Import fails:

  • Verify export file is valid ZIP format

  • Check Apicurio Registry 3.x has sufficient storage

  • Review registry v3 logs for specific errors

  • If partial import occurred, drop v3 database (or Kafka topic) and retry

Baseline metrics mismatch:

  • Review import logs for skipped artifacts

  • Check for import errors or warnings

  • Verify export file integrity

  • Consider re-exporting and re-importing

Rollback needed:

  1. Switch load balancer back to 2.6.3

  2. Investigate v3 issues

  3. Recovery time: 30-60 seconds

  4. v2 data unchanged (export was read-only)

Migrating Apicurio Registry data

Use the export and import APIs to migrate persisted content from Apicurio Registry 2.6.3 to a new Apicurio Registry 3.x deployment. The APIs preserve artifact identifiers, metadata, and references, ensuring downstream Kafka payloads remain compatible.

You must use the export/import procedure for migration. Apicurio Registry 3.x cannot directly read 2.6.3 storage because the underlying data structures have changed significantly:
  • SQL storage: The v3 database schema is completely redesigned and incompatible with v2. The data model changes (separate artifact and version metadata, new branch support) require a different table structure.

  • KafkaSQL storage: The v3 Kafka journal topic uses a new event journaling format that is incompatible with v2. The v2 topic cannot be reused.

Export data from v2 and import it into v3 using the export/import APIs. The import process automatically transforms the data to the v3 format.

Apicurio Registry 3.x accepts the export archive generated from a 2.6.3 instance. Capture the archive from your existing deployment, provision the 3.x environment, and import the archive into the new cluster.

Prerequisites
  • Ensure both the source Apicurio Registry 2.6.3 server and the destination 3.x server are currently running.

  • Administrative credentials that allow access to the /apis/registry/v2/admin/export and /apis/registry/v3/admin/import endpoints.

  • If using OAuth2 authentication, valid client credentials with admin role (for example, sr-admin).

Procedure

The migration scripts automate the export, import, and validation process. They support OAuth2 authentication and provide detailed error handling.

  1. Export all data from Apicurio Registry 2.6.3 using the export script:

    ./apicurio-export-registry-data.sh

    The script:

    • Connects to your 2.6.3 deployment

    • Exports all artifacts, versions, metadata, and rules

    • Saves the data to a ZIP file (default: registry-export.zip)

    • Validates the export file format and size

    • Reports export duration and file details

      For detailed configuration options and OAuth2 authentication setup, see Migration scripts reference.

  2. Import the export archive into Apicurio Registry 3.x using the import script:

    ./apicurio-import-registry-data.sh

    The script:

    • Validates the import ZIP file exists and is valid

    • Checks Apicurio Registry 3.x accessibility and version

    • Imports all data from the export file

    • Verifies artifact counts before and after import

    • Reports global rules configuration

      For detailed configuration options, see Migration scripts reference.

  3. Validate the imported data using the verification script:

    ./apicurio-verify-registry-version.sh

    The script performs comprehensive validation:

    • Health endpoint verification

    • System information and version check

    • Artifact count comparison

    • Global rules validation

    • v2 API backward compatibility check (optional)

      For detailed configuration options, see Migration scripts reference.

Additional resources

Migrating Apicurio Registry client applications

Review every application that integrates with Apicurio Registry 2.6.3 to verify compatibility with the v3 REST API, SDKs, and client libraries. Update dependency coordinates, reconfigure endpoints, and adjust automation to account for the new data model.

Before you begin

Ensure you have the following:

  • Existing Apicurio Registry 2.6.3 applications that rely on the v2 REST API or legacy client libraries.

  • Access to the source code or deployment configuration for each application you must update.

  • Understanding of your client application types (Kafka SerDes, REST API clients, SDK-based applications).

  • Required dependencies for running migration scripts. See Installing dependencies.

Apicurio Registry 3.x maintains backward compatibility with v2 client libraries and SerDes. You can continue using v2 clients with a v3 registry during your migration period, allowing gradual client updates.
Backward compatibility

Apicurio Registry 3.x provides backward compatibility for existing v2 clients:

  • v2 REST API remains available at /apis/registry/v2

  • v2 SerDes libraries continue to work with v3 registry

  • v3 SerDes can consumes v2 client Kafka messages (with proper configuration)

  • No immediate client updates required during migration

This approach lets you:

  1. Migrate the registry to v3 first.

  2. Test with existing v2 clients.

  3. Gradually update clients to v3 libraries over time.

Choosing a migration strategy

Gradual migration

Migrate registry first, then update clients incrementally:

  1. Deploy Apicurio Registry 3.x

  2. Verify v2 clients continue working

  3. Update high-priority clients to v3 SerDes or SDKs

  4. Gradually migrate remaining clients

  5. Deprecate v2 API access once all clients updated

Benefits:

  • Lower risk: clients continue working during migration

  • Flexible timeline for client updates

  • Easier rollback if issues occur

Big-bang migration

Update all clients and registry simultaneously:

  1. Prepare all client updates in advance

  2. Deploy Apicurio Registry 3.x

  3. Deploy updated client applications

  4. Verify all integrations work

Benefits:

  • Clean cutover to v3

  • No mixed v2/v3 client environment

Risks:

  • Higher complexity and coordination required

  • More difficult to troubleshoot if issues arise

Migrating Kafka SerDes applications

Kafka SerDes applications require careful migration planning.

Maven dependency changes

Update SerDes library dependencies from v2 to v3:

Registry 2.x dependencies:

<dependency>
    <groupId>io.apicurio</groupId>
    <artifactId>apicurio-registry-serdes-avro-serde</artifactId>
    <version>2.6.13.Final</version>
</dependency>

Registry 3.x dependencies:

<dependency>
    <groupId>io.apicurio</groupId>
    <artifactId>apicurio-registry-avro-serde-kafka</artifactId>
    <version>3.1.2</version>
</dependency>
Artifact IDs changed in v3. The v2 artifact ID was apicurio-registry-serdes-avro-serde, while v3 uses apicurio-registry-avro-serde-kafka.
Configuration changes

Update SerDes configuration properties for v3:

Registry 2.x SerDes configuration:

Properties props = new Properties();

// v2 SerDes configuration
props.put(SerdeConfig.REGISTRY_URL, "https://registry-v2.example.com/apis/registry/v2");
props.put(SerdeConfig.AUTO_REGISTER_ARTIFACT, Boolean.TRUE);
props.put(SerdeConfig.ENABLE_HEADERS, false);
props.put(SerdeConfig.ENABLE_CONFLUENT_ID_HANDLER, true);
props.put(SerdeConfig.USE_ID, IdOption.contentId.name());

// v2 OAuth2 configuration
props.put(SerdeConfig.AUTH_SERVICE_URL, "https://keycloak.example.com");
props.put(SerdeConfig.AUTH_REALM, "registry");
props.put(SerdeConfig.AUTH_CLIENT_ID, "kafka-client");
props.put(SerdeConfig.AUTH_CLIENT_SECRET, "secret");

Registry 3.x SerDes configuration:

Properties props = new Properties();

// v3 SerDes configuration
props.put(SerdeConfig.REGISTRY_URL, "https://registry-v3.example.com/apis/registry/v3");
props.put(SerdeConfig.AUTO_REGISTER_ARTIFACT, Boolean.TRUE);

// v3 OAuth2 configuration (simplified)
props.put(SerdeConfig.AUTH_TOKEN_ENDPOINT, "https://keycloak.example.com/realms/registry/protocol/openid-connect/token");
props.put(SerdeConfig.AUTH_CLIENT_ID, "kafka-client");
props.put(SerdeConfig.AUTH_CLIENT_SECRET, "secret");

Key configuration differences:

Property Registry 2.x Registry 3.x

OAuth2 endpoint

AUTH_SERVICE_URL + AUTH_REALM

AUTH_TOKEN_ENDPOINT (full URL)

ID Handler

ID_HANDLER (optional default "8 byte handler")

ID_HANDLER (optional default "4 byte handler")

Confluent ID handler

ENABLE_CONFLUENT_ID_HANDLER (optional convenience property)

Removed

Content ID usage

USE_ID with IdOption (default "globalId")

USE_ID with IdOption (default "contentId")

The default ID option changed from globalId to contentId in v3. Both v2 and v3 SerDes can read messages using either ID type, ensuring compatibility during migration. If your v2 applications explicitly set USE_ID=contentId, you can remove this configuration in v3 as it is now the default.
TLS and HTTPS configuration

TLS configuration differs between v2 and v3 SerDes clients. Update your configuration as follows:

Registry 2.x (system properties):

// v2 SerDes clients use system properties for TLS configuration
System.setProperty("javax.net.ssl.trustStore", "/path/to/truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "password");

Registry 3.x (SerdeConfig properties):

// v3 SerDes clients use SerdeConfig properties for TLS configuration
Properties props = new Properties();

// Configure trust store for Registry HTTPS connections
props.put(SerdeConfig.TLS_TRUSTSTORE_LOCATION, "/path/to/truststore.jks");
props.put(SerdeConfig.TLS_TRUSTSTORE_PASSWORD, "password");
props.put(SerdeConfig.TLS_TRUSTSTORE_TYPE, "JKS");

// System properties for OAuth2 Keycloak connections
System.setProperty("javax.net.ssl.trustStore", "/path/to/truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "password");
v3 SerDes requires both SerdeConfig TLS properties (for Registry SDK connections) and system properties (for OAuth2 Keycloak connections). This is different from v2, which only used system properties.
Message format compatibility

With proper configuration, Apicurio Registry 3.x SerDes reads messages serialized by v2 SerDes:

  • v3 consumers read messages produced by v2 producers

  • v2 consumers read messages produced by v3 producers

  • Mixed environment (v2 and v3 clients) is fully supported

This helps avoid data loss during migration.

Migrating REST API clients

For applications using Apicurio Registry REST API directly (not Kafka SerDes):

SDK migration

Update to v3 Kiota-generated SDKs:

Registry 2.x SDK:

<dependency>
    <groupId>io.apicurio</groupId>
    <artifactId>apicurio-registry-client</artifactId>
    <version>2.6.13.Final</version>
</dependency>

Registry 3.x SDK:

<dependency>
    <groupId>io.apicurio</groupId>
    <artifactId>apicurio-registry-java-sdk</artifactId>
    <version>3.1.2</version>
</dependency>
TLS and HTTPS configuration

TLS configuration differs between v2 and v3 clients. Update your configuration as follows:

Registry 2.x (system properties):

// v2 clients use system properties
System.setProperty("javax.net.ssl.trustStore", "/path/to/truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "password");

Registry 3.x (RegistryClientOptions):

// v3 clients use RegistryClientOptions
RegistryClientOptions options = RegistryClientOptions.builder()
    .trustStore(new File("/path/to/truststore.jks"))
    .trustStorePassword("password")
    .build();

props.put(SerdeConfig.REGISTRY_CLIENT_OPTIONS, options);
Migrating client authentication

OAuth2/OIDC configuration changes for REST API client applications:

Registry 2.x client authentication:

import io.apicurio.registry.rest.client.RegistryClient;
import io.apicurio.registry.rest.client.RegistryClientFactory;
import io.apicurio.rest.client.auth.Auth;
import io.apicurio.rest.client.auth.OidcAuth;
import io.apicurio.rest.client.auth.exception.AuthErrorHandler;
import io.apicurio.rest.client.spi.ApicurioHttpClient;
import io.apicurio.rest.client.spi.ApicurioHttpClientFactory;

// v2 clients configure auth server URL, not the full token URL
String authServerUrl = "https://keycloak.example.com/realms/registry";
String clientId = "my-client";
String clientSecret = "my-secret";

// Create HTTP client for OIDC authentication
ApicurioHttpClient httpClient = ApicurioHttpClientFactory.create(authServerUrl,
    new AuthErrorHandler());

// Create OIDC auth with client credentials
Auth auth = new OidcAuth(httpClient, clientId, clientSecret, null, null);

// Create registry client with auth
RegistryClient client = RegistryClientFactory.create(registryUrl, Collections.emptyMap(), auth);

Registry 3.x SDK authentication:

import io.apicurio.registry.client.RegistryClientFactory;
import io.apicurio.registry.client.RegistryClientOptions;
import io.apicurio.registry.rest.client.RegistryClient;

// v3 clients use RegistryClientOptions builder with full token endpoint URL
String tokenEndpoint = "https://keycloak.example.com/realms/registry/protocol/openid-connect/token";
String clientId = "my-client";
String clientSecret = "my-secret";

// Create options with OAuth2 client credentials
RegistryClientOptions options = RegistryClientOptions.create(registryUrl)
    .oauth2(tokenEndpoint, clientId, clientSecret, null);

// Create registry client
RegistryClient client = RegistryClientFactory.create(options);

Key authentication differences:

Aspect Registry 2.x Registry 3.x

Configuration approach

Separate Auth object with OidcAuth

Fluent builder with RegistryClientOptions

OAuth2 endpoint

Full auth server URL with realm path

Full OIDC token endpoint URL

Factory method

RegistryClientFactory.create(url, map, auth)

RegistryClientFactory.create(options)

Updating Apicurio Registry configuration

Configuration keys in Apicurio Registry 3.x adopt a unified apicurio. namespace and reorganize authentication, eventing, UI, and storage settings. Review and update your deployment descriptors to match the new naming scheme.

Configuration property changes are extensive in 3.x. Review all sections carefully and test in a staging environment before migrating production deployments.
Understanding configuration changes

Apicurio Registry 3.x introduces major configuration changes:

  • Namespace consolidation: Most properties now use the apicurio. prefix

  • Storage configuration: Database settings moved out of quarkus.datasource.* namespace

  • Authentication: OAuth2/OIDC configuration uses full realm URLs

  • KafkaSQL: New apicurio.kafkasql.* namespace with different topic requirements

  • API features: New granular deletion control properties

Configuring storage

SQL storage (PostgreSQL, MySQL, H2)

You must use separate database instances or schemas for v2 and v3 because the database schemas are incompatible.

Registry 2.x property Registry 3.x property

REGISTRY_DATASOURCE_URL

APICURIO_DATASOURCE_URL

REGISTRY_DATASOURCE_USERNAME

APICURIO_DATASOURCE_USERNAME

REGISTRY_DATASOURCE_PASSWORD

APICURIO_DATASOURCE_PASSWORD

QUARKUS_DATASOURCE_DB_KIND

Not required (auto-detected from URL)

REGISTRY_SQL_INIT

APICURIO_SQL_INIT

Not applicable

APICURIO_STORAGE_KIND=sql (required)

Not applicable

APICURIO_STORAGE_SQL_KIND (PostgreSQL, MySQL, H2)

Example migration:

# Registry 2.x SQL configuration
REGISTRY_DATASOURCE_URL=jdbc:postgresql://postgres:5432/registry
REGISTRY_DATASOURCE_USERNAME=apicurio
REGISTRY_DATASOURCE_PASSWORD=password123
QUARKUS_DATASOURCE_DB_KIND=postgresql

# Registry 3.x SQL configuration
APICURIO_STORAGE_KIND=sql
APICURIO_STORAGE_SQL_KIND=postgresql
APICURIO_DATASOURCE_URL=jdbc:postgresql://postgres:5432/registry_v3
APICURIO_DATASOURCE_USERNAME=apicurio
APICURIO_DATASOURCE_PASSWORD=password123
Use separate database instances or different database names for v2 and v3. The v3 database schema is incompatible with v2.
KafkaSQL storage

You must use a different Kafka topic for v3 than v2 because the journal formats are incompatible.

Registry 2.x property Registry 3.x property

KAFKA_BOOTSTRAP_SERVERS

APICURIO_KAFKASQL_BOOTSTRAP_SERVERS

REGISTRY_KAFKASQL_TOPIC

APICURIO_KAFKASQL_TOPIC

REGISTRY_KAFKASQL_CONSUMER_GROUP_ID

APICURIO_KAFKASQL_CONSUMER_GROUP_ID (optional)

Not applicable

APICURIO_STORAGE_KIND=kafkasql (required)

Example migration:

# Registry 2.x KafkaSQL configuration
KAFKA_BOOTSTRAP_SERVERS=kafka:9092
REGISTRY_KAFKASQL_TOPIC=kafkasql-journal-v2
REGISTRY_KAFKASQL_CONSUMER_GROUP_ID=registry-v2-consumer

# Registry 3.x KafkaSQL configuration
APICURIO_STORAGE_KIND=kafkasql
APICURIO_KAFKASQL_BOOTSTRAP_SERVERS=kafka:9092
APICURIO_KAFKASQL_TOPIC=kafkasql-journal-v3
Use a different topic name for v3 (kafkasql-journal-v3) than v2 (kafkasql-journal-v2). The v3 journal format is incompatible with v2.
Understanding KafkaSQL storage

Apicurio Registry 3.x completely re-engineers the KafkaSQL storage implementation with significant architectural improvements.

Architectural changes in v3

Apicurio Registry 3.x introduces a fundamentally different KafkaSQL implementation:

  • True journaling approach: The new implementation uses a true event journaling pattern

  • No log compaction: Unlike v2, the v3 implementation does not rely on Kafka log compaction

  • Immutable event log: All registry operations are stored as immutable events in the journal topic

  • Improved consistency: Better handling of concurrent operations and edge cases

Kafka topic configuration

The v3 KafkaSQL journal topic requires specific Kafka topic settings:

Cleanup policy:

# v3 KafkaSQL topic must use "delete" cleanup policy (NOT "compact")
cleanup.policy=delete

# Set infinite retention to preserve all journal events
retention.ms=-1
retention.bytes=-1
Configure the journal topic with cleanup.policy=delete and infinite retention (retention.ms=-1). Do not use log compaction. You must preserve all journal events for proper registry operation.

Creating the topic:

# Create v3 KafkaSQL topic with correct settings
kafka-topics.sh --bootstrap-server kafka:9092 --create \
  --topic kafkasql-journal-v3 \
  --partitions 1 \  (1)
  --replication-factor 3 \
  --config cleanup.policy=delete \
  --config retention.ms=-1 \
  --config retention.bytes=-1
1 The partition count is configurable. All journal messages use a global partition key for ordering, so a single partition is sufficient. Adjust based on your Kafka cluster configuration.

Verifying topic configuration:

# Check topic configuration
kafka-topics.sh --bootstrap-server kafka:9092 --describe \
  --topic kafkasql-journal-v3

# Should show:
#   cleanup.policy=delete
#   retention.ms=-1
#   retention.bytes=-1
Snapshotting feature (advanced)

Apicurio Registry 3.x KafkaSQL includes an optional snapshotting feature for advanced use cases.

What is snapshotting?

Snapshotting creates periodic database snapshots of the registry state, providing:

  • Faster startup times: Registry loads from the snapshot instead of replaying the entire journal

  • Backup capability: Use snapshots for disaster recovery

  • Optional journal cleanup: When snapshotting is enabled, you can configure finite retention to remove older journal events

When to use snapshotting:

  • Large registries with many artifacts (thousands+)

  • Long-running deployments with growing journal topics

  • Need for faster registry startup/recovery times

Without snapshotting enabled, you must preserve all journal events (infinite retention). If you enable snapshotting and want to use finite retention, set apicurio.kafkasql.topic-configuration-verification-override-enabled=true and ensure snapshots are created more frequently than messages are deleted.
Snapshotting is an advanced feature. Most deployments do not need snapshotting enabled. Consult the official Apicurio Registry documentationfor more information on how to configure and use the snapshotting feature.
Configuring authentication and authorization

Authentication configuration changes significantly in 3.x, particularly for OAuth2/OIDC integration. Update your configuration properties as shown in the following table.

Registry 2.x property Registry 3.x property

AUTH_ENABLED

QUARKUS_OIDC_TENANT_ENABLED

KEYCLOAK_URL

Use QUARKUS_OIDC_AUTH_SERVER_URL with full realm path

KEYCLOAK_REALM

Included in QUARKUS_OIDC_AUTH_SERVER_URL

KEYCLOAK_API_CLIENT_ID

QUARKUS_OIDC_CLIENT_ID

ROLE_BASED_AUTHZ_ENABLED

APICURIO_AUTH_ROLE-BASED-AUTHORIZATION

REGISTRY_AUTH_ROLES_ADMIN

APICURIO_AUTH_ROLES_ADMIN

REGISTRY_AUTH_ROLES_DEVELOPER

APICURIO_AUTH_ROLES_DEVELOPER

REGISTRY_AUTH_ROLES_READONLY

APICURIO_AUTH_ROLES_READONLY

QUARKUS_OIDC_TLS_VERIFICATION

QUARKUS_OIDC_TLS_VERIFICATION (same)

Example migration with Keycloak:

# Registry 2.x authentication
AUTH_ENABLED=true
KEYCLOAK_URL=https://keycloak:8443
KEYCLOAK_REALM=registry
KEYCLOAK_API_CLIENT_ID=registry-api
ROLE_BASED_AUTHZ_ENABLED=true
REGISTRY_AUTH_ROLES_ADMIN=sr-admin
REGISTRY_AUTH_ROLES_DEVELOPER=sr-developer
REGISTRY_AUTH_ROLES_READONLY=sr-readonly

# Registry 3.x authentication
QUARKUS_OIDC_TENANT_ENABLED=true
QUARKUS_OIDC_AUTH_SERVER_URL=https://keycloak:8443/realms/registry
QUARKUS_OIDC_CLIENT_ID=registry-api
APICURIO_AUTH_ROLE-BASED-AUTHORIZATION=true
APICURIO_AUTH_ROLES_ADMIN=sr-admin
APICURIO_AUTH_ROLES_DEVELOPER=sr-developer
APICURIO_AUTH_ROLES_READONLY=sr-readonly
The QUARKUS_OIDC_AUTH_SERVER_URL property in v3 requires the full realm path (for example, https://keycloak.example.com/realms/registry). In v2, you specified the realm using a separate property.
Configuring API and deletion settings

Apicurio Registry 3.x introduces granular control over deletion operations.

Registry 2.x property Registry 3.x property

REGISTRY_REST_ARTIFACT_DELETION_ENABLED

APICURIO_REST_DELETION_ARTIFACT_ENABLED

Not available

APICURIO_REST_DELETION_ARTIFACT-VERSION_ENABLED

Not available

APICURIO_REST_DELETION_GROUP_ENABLED

REGISTRY_UI_FEATURES_READONLY

APICURIO_UI_FEATURES_READ-ONLY_ENABLED

CORS_ALLOWED_ORIGINS

QUARKUS_HTTP_CORS_ORIGINS

Example migration:

# Registry 2.x API configuration
REGISTRY_REST_ARTIFACT_DELETION_ENABLED=true
REGISTRY_UI_FEATURES_READONLY=false
CORS_ALLOWED_ORIGINS=*

# Registry 3.x API configuration
APICURIO_REST_DELETION_ARTIFACT_ENABLED=true
APICURIO_REST_DELETION_ARTIFACT-VERSION_ENABLED=true
APICURIO_REST_DELETION_GROUP_ENABLED=true
APICURIO_UI_FEATURES_READ-ONLY_ENABLED=false
QUARKUS_HTTP_CORS_ORIGINS=*
Configuring TLS/HTTPS

TLS configuration remains unchanged between v2 and v3 for server-side settings. Use the same properties as shown in the following table.

Registry 2.x property Registry 3.x property

QUARKUS_HTTP_SSL_PORT

QUARKUS_HTTP_SSL_PORT (same)

QUARKUS_HTTP_SSL_CERTIFICATE_KEY_STORE_FILE

QUARKUS_HTTP_SSL_CERTIFICATE_KEY_STORE_FILE (same)

QUARKUS_HTTP_SSL_CERTIFICATE_KEY_STORE_PASSWORD

QUARKUS_HTTP_SSL_CERTIFICATE_KEY_STORE_PASSWORD (same)

QUARKUS_HTTP_INSECURE_REQUESTS

QUARKUS_HTTP_INSECURE_REQUESTS (same)

Example (same for v2 and v3):

# TLS configuration (unchanged)
QUARKUS_HTTP_SSL_PORT=8443
QUARKUS_HTTP_SSL_CERTIFICATE_KEY_STORE_FILE=/certs/registry-keystore.p12
QUARKUS_HTTP_SSL_CERTIFICATE_KEY_STORE_PASSWORD=password123
QUARKUS_HTTP_INSECURE_REQUESTS=disabled
TLS configuration is identical for v2 and v3. If the hostname and routes remain the same, reuse the same certificates.
Using the migration checklist
  1. Inventory all configuration files, including deployment manifests, application.properties, and environment variables.

  2. Create a mapping spreadsheet documenting v2 properties and their v3 equivalents.

  3. Update configuration for v3 deployment:

    • Storage: Change database name or topic name

    • Authentication: Update to full realm URL format

    • Properties: Apply apicurio.* namespace

  4. Deploy v3 to staging environment with updated configuration.

  5. Monitor startup logs for configuration errors or warnings.

  6. Test all functionality:

    • Storage connectivity

    • Authentication and authorization

    • API operations (create, read, update, delete)

    • UI access

  7. Document any custom or undocumented properties for future reference.

Issue: v3 fails to start with "Storage not configured"

Symptoms: * Registry pod/container fails to start * Logs show: Storage kind not configured

Cause: Missing APICURIO_STORAGE_KIND property.

Solution:

# For SQL storage
APICURIO_STORAGE_KIND=sql
APICURIO_STORAGE_SQL_KIND=postgresql

# For KafkaSQL storage
APICURIO_STORAGE_KIND=kafkasql
Issue: v3 authentication fails with "User is not authenticated"

Symptoms: * All API requests return 401 Unauthorized * Even with valid access token

Cause: Incorrect OAuth2/OIDC configuration, typically missing realm path.

Solution:

Check that QUARKUS_OIDC_AUTH_SERVER_URL includes the full realm path:

# Wrong (v2 style)
QUARKUS_OIDC_AUTH_SERVER_URL=https://keycloak:8443

# Correct (v3 requires realm path)
QUARKUS_OIDC_AUTH_SERVER_URL=https://keycloak:8443/realms/registry

Verify Keycloak is accessible from the registry container:

curl -k https://keycloak:8443/realms/registry/.well-known/openid-configuration
Issue: Database connection fails

Symptoms: * Registry fails to start * Logs show JDBC connection errors

Cause: Using old REGISTRY_DATASOURCE_* or QUARKUS_DATASOURCE_* properties.

Solution:

Update to v3 datasource properties:

# Remove these v2 properties
# REGISTRY_DATASOURCE_URL=...
# REGISTRY_DATASOURCE_USERNAME=...

# Use v3 properties
APICURIO_DATASOURCE_URL=jdbc:postgresql://postgres:5432/registry_v3
APICURIO_DATASOURCE_USERNAME=apicurio
APICURIO_DATASOURCE_PASSWORD=password123
Issue: CORS errors in browser when accessing UI

Symptoms: * UI loads but API calls fail * Browser console shows CORS errors

Cause: CORS property name changed in v3.

Solution:

# Wrong (v2 property name)
CORS_ALLOWED_ORIGINS=*

# Correct (v3 property name)
QUARKUS_HTTP_CORS_ORIGINS=*
Issue: Role-based authorization not working

Symptoms: * Users can access registry but cannot perform admin operations * No 403 Forbidden errors, but operations fail silently

Cause: Role configuration properties not updated to v3 namespace.

Solution:

# Update all role properties
APICURIO_AUTH_ROLE-BASED-AUTHORIZATION=true
APICURIO_AUTH_ROLES_ADMIN=sr-admin
APICURIO_AUTH_ROLES_DEVELOPER=sr-developer
APICURIO_AUTH_ROLES_READONLY=sr-readonly

Verify user has correct roles in Keycloak and token includes expected roles:

# Decode JWT token to check roles
echo $ACCESS_TOKEN | cut -d. -f2 | base64 -d | jq .realm_access.roles
Additional resources

User interface changes

Apicurio Registry 3.x introduces a significant architectural change to the user interface. You deploy the UI as a separate container, providing more deployment flexibility but requiring additional configuration considerations during migration.

Separate UI container

In Apicurio Registry 2.6.3, the UI is built into the main apicurio-registry container as a single monolithic application. Apicurio Registry 3.x separates the UI into its own container:

Registry 2.x architecture:

┌─────────────────────────────┐
│  apicurio-registry-sql:2.x  │
│  ┌───────────┬────────────┐ │
│  │    UI     │    API     │ │
│  └───────────┴────────────┘ │
└─────────────────────────────┘

Registry 3.x architecture:

┌────────────────────┐    ┌────────────────────┐
│ apicurio-registry  │    │ apicurio-registry  │
│       -ui:3.x      │    │       :3.x         │
│                    │    │                    │
│   UI (Frontend)    │───▶│   API (Backend)    │
└────────────────────┘    └────────────────────┘

Implications for migration:

  • Two containers to deploy and manage instead of one

  • Additional networking configuration required

  • More flexible deployment options

  • Independent scaling of UI and API components

Choosing deployment options

You have flexibility in how you deploy the UI container in relation to the API container. Choose one of the following options.

Option 1: Separate subdomains

Deploy UI and API to separate subdomains:

# UI accessible at: https://registry-ui.example.com
apicurio-registry-ui:
  image: apicurio/apicurio-registry-ui:3.1.2
  ports:
    - "443:8443"
  environment:
    - REGISTRY_API_URL=https://registry-api.example.com/apis/registry/v3

# API accessible at: https://registry-api.example.com
apicurio-registry:
  image: apicurio/apicurio-registry:3.1.2
  ports:
    - "443:8443"

Benefits: * Clean separation of concerns * Independent DNS configuration * Easier to scale components independently

Option 2: Co-located with reverse proxy

Use a reverse proxy (nginx, HAProxy) to serve both UI and API from the same domain:

# Example: nginx routing configuration
# UI at: https://registry.example.com/ui/
# API at: https://registry.example.com/app/

services:
  apicurio-registry:
    image: apicurio/apicurio-registry:3.1.2
    environment:
      - apicurio.app.context-path=/app/
      - QUARKUS_HTTP_CORS_ORIGINS=*

  apicurio-registry-ui:
    image: apicurio/apicurio-registry-ui:3.1.2
    environment:
      - REGISTRY_CONTEXT_PATH=/ui/
      - REGISTRY_API_URL=/app/apis/registry/v3
      - REGISTRY_DOCS_URL=/ui/docs/
      - REGISTRY_EDITORS_URL=/ui/editors/

  nginx:
    image: nginx
    ports:
      - "443:8443"
    # nginx.conf routes:
    #   /ui/* → apicurio-registry-ui
    #   /app/* → apicurio-registry

Benefits: * Single domain for users * Simpler certificate management * Avoids CORS complexity

Application container configuration (primary)

Configure most UI settings through the application (API) container, not the UI container. The application serves UI configuration to the frontend.

Available UI properties (configured on application container):

Property Description Default

apicurio.ui.contextPath

Context path of the UI

/

apicurio.ui.navPrefixPath

Navigation prefix for all UI paths

/

apicurio.ui.docsUrl

URL of the documentation component

/docs/

apicurio.ui.editorsUrl

URL of the editors component (Designer)

/editors/

apicurio.ui.auth.oidc.redirect-uri

OAuth2/OIDC redirect URI

/

apicurio.ui.auth.oidc.client-id

OAuth2/OIDC client ID for UI

apicurio-registry-ui

apicurio.ui.auth.oidc.logout-url

OAuth2/OIDC logout URL

f5

apicurio.ui.auth.oidc.scope

OAuth2/OIDC scope

openid profile email

apicurio.ui.features.read-only.enabled

Enable read-only mode for UI

false

apicurio.ui.features.breadcrumbs

Show breadcrumbs in UI

true

apicurio.ui.features.settings

Show Settings tab in UI

true

Example application container configuration:

# UI configuration (on apicurio-registry container)
apicurio.ui.contextPath=/
apicurio.ui.editorsUrl=/editors/
apicurio.ui.auth.oidc.client-id=registry-ui-client
apicurio.ui.auth.oidc.scope=openid profile email
apicurio.ui.features.read-only.enabled=false
UI container configuration (overrides)

The UI container has its own environment variables that override the application configuration, but you typically do not need these.

Common UI container environment variables:

Environment Variable Description

REGISTRY_API_URL

Required: URL to the backend API (for example, http://registry-api:8080/apis/registry/v3)

REGISTRY_CONTEXT_PATH

Override for UI context path

REGISTRY_NAV_PREFIX_PATH

Override for navigation prefix path

REGISTRY_DOCS_URL

Override for documentation URL

REGISTRY_EDITORS_URL

Override for editors (Designer) URL

REGISTRY_AUTH_URL

Override for OAuth2/OIDC auth server URL

REGISTRY_AUTH_CLIENT_ID

Override for OAuth2/OIDC client ID

REGISTRY_FEATURE_READ_ONLY

Override for read-only mode (true or false)

The only required UI container property is REGISTRY_API_URL. Configure all other UI settings on the application container using apicurio.ui.* properties.
Using Designer functionality

Apicurio Registry 3.1.0 introduces integrated Designer functionality, replacing the standalone Apicurio Studio project.

What is Designer?

Designer provides visual editing capabilities for OpenAPI and AsyncAPI specifications directly within the Apicurio Registry UI. This functionality previously existed as a separate project (Apicurio Studio) but is now fully integrated into Apicurio Registry.

Key features:

  • Visual editor for OpenAPI 3.x specifications

  • Visual editor for AsyncAPI specifications

  • Draft artifact version state for work-in-progress designs

  • Direct integration with Apicurio Registry storage

  • No separate deployment required

Enabling Designer

Designer functionality requires enabling content mutability for artifact versions:

# Enable Designer functionality
apicurio.rest.mutability.artifact-version-content.enabled=true

When enabled, users with the developer or admin role can:

  • Create draft versions of artifacts

  • Edit draft content using the visual editor

  • Save changes iteratively

  • Finalize drafts to create immutable versions

Additional resources

Migration scripts reference

The migration scripts automate key steps in the workflow. All scripts support interactive and automated modes using environment variables, with OAuth2 authentication support.

Understanding migration scripts

The migration scripts are production-ready tools that handle the most critical and error-prone aspects of migration:

  • apicurio-capture-metrics.sh - Captures metrics before/after migration (for comparison)

  • apicurio-export-registry-data.sh - Exports all data from 2.6.3

  • apicurio-import-registry-data.sh - Imports data into Apicurio Registry 3.x

  • apicurio-verify-registry-version.sh - Verifies registry version and health

  • apicurio-verify-v3-api-features.sh - Tests v3-specific API features

Find all scripts in the Apicurio Registry GitHub repository under docs/scripts/.

Understanding common features

All migration scripts share these common features:

Interactive and automated modes:

  • Interactive mode: Scripts prompt for required inputs with sensible defaults

  • Automated mode: Set environment variables to skip prompts (useful for CI/CD)

OAuth2 authentication support:

  • Client credentials grant type

  • Configurable token endpoint and client credentials

  • Optional: Run without authentication for testing environments

TLS/HTTPS support:

  • Works with trusted certificates by default

  • Option to skip TLS verification for development/testing (SKIP_TLS_VERIFY=true)

Clear output and error handling:

  • Color-coded output (info, success, warning, error)

  • Detailed progress indicators

  • Clear exit codes for automation (0 = success, 1 = failure)

Script: apicurio-capture-metrics.sh

Purpose: Captures metrics from registry before and after migration.

What it captures:

  • Total artifact count

  • Sample of up to 5 artifacts with full metadata

  • Global rule configurations

  • Output saved to text file for post-migration comparison

Usage (interactive):

./apicurio-capture-metrics.sh

Usage (automated):

export REGISTRY_URL="https://registry.example.com"
export REGISTRY_API_VERSION="v2"
export AUTH_ENABLED="true"
export AUTH_TOKEN_URL="https://keycloak.example.com/realms/registry/protocol/openid-connect/token"
export AUTH_CLIENT_ID="admin-client"
export AUTH_CLIENT_SECRET="your-secret"
export OUTPUT_FILE="registry-baseline.txt"

./apicurio-capture-metrics.sh

Environment variables:

Variable Description

REGISTRY_URL

Registry base URL (for example, https://registry.example.com)

REGISTRY_API_VERSION

API version to use (default: v2)

AUTH_ENABLED

Set to true to enable OAuth2 authentication

AUTH_TOKEN_URL

OAuth2 token endpoint URL

AUTH_CLIENT_ID

OAuth2 client ID

AUTH_CLIENT_SECRET

OAuth2 client secret

OUTPUT_FILE

Output file path (default: registry-baseline.txt)

SKIP_TLS_VERIFY

Set to true to skip TLS certificate verification

Output:

Text file containing artifact summary and global rules (default: registry-baseline.txt).

Script: apicurio-export-registry-data.sh

Purpose: Exports all data from 2.6.3 deployment to a ZIP file.

What it exports:

  • All artifacts and versions

  • Artifact metadata (labels, properties, descriptions)

  • Global and artifact-specific rules

  • Artifact references

Usage (interactive):

./apicurio-export-registry-data.sh

Usage (automated):

export REGISTRY_URL="https://registry-v2.example.com"
export REGISTRY_API_VERSION="v2"
export AUTH_ENABLED="true"
export AUTH_TOKEN_URL="https://keycloak.example.com/realms/registry/protocol/openid-connect/token"
export AUTH_CLIENT_ID="admin-client"
export AUTH_CLIENT_SECRET="your-secret"
export EXPORT_FILE="registry-export.zip"

./apicurio-export-registry-data.sh

Environment variables:

Variable Description

REGISTRY_URL

Registry base URL (for example, https://registry-v2.example.com)

REGISTRY_API_VERSION

API version to use (default: v2)

AUTH_ENABLED

Set to true to enable OAuth2 authentication

AUTH_TOKEN_URL

OAuth2 token endpoint URL

AUTH_CLIENT_ID

OAuth2 client ID

AUTH_CLIENT_SECRET

OAuth2 client secret

EXPORT_FILE

Export file path (default: registry-export.zip)

SKIP_TLS_VERIFY

Set to true to skip TLS certificate verification

Output:

ZIP file containing complete registry export (default: registry-export.zip).

Important notes:

  • Run this script while the registry is in read-only mode to maintain data consistency

  • The export file size varies depending on registry size

Script: apicurio-import-registry-data.sh

Purpose: Imports data from a v2 export file into Apicurio Registry 3.x deployment.

What it does:

  • Validates the import ZIP file

  • Checks Apicurio Registry 3.x accessibility and version

  • Imports all data from the export file

  • Verifies artifact count after import

  • Reports global rules configuration

Usage (interactive):

./apicurio-import-registry-data.sh

Usage (automated):

export REGISTRY_URL="https://registry-v3.example.com"
export REGISTRY_API_VERSION="v3"
export AUTH_ENABLED="true"
export AUTH_TOKEN_URL="https://keycloak.example.com/realms/registry/protocol/openid-connect/token"
export AUTH_CLIENT_ID="admin-client"
export AUTH_CLIENT_SECRET="your-secret"
export IMPORT_FILE="registry-export.zip"

./apicurio-import-registry-data.sh

Environment variables:

Variable Description

REGISTRY_URL

Registry base URL (for example, https://registry-v3.example.com)

REGISTRY_API_VERSION

API version to use (default: v3)

AUTH_ENABLED

Set to true to enable OAuth2 authentication

AUTH_TOKEN_URL

OAuth2 token endpoint URL

AUTH_CLIENT_ID

OAuth2 client ID

AUTH_CLIENT_SECRET

OAuth2 client secret

IMPORT_FILE

Import file path (default: registry-export.zip)

SKIP_TLS_VERIFY

Set to true to skip TLS certificate verification

Important notes:

  • Import adds to existing data (does not replace)

  • Script warns if registry already contains artifacts

  • Import into an empty v3 registry for best results

Script: apicurio-verify-registry-version.sh

Purpose: Verifies the version and health of a Apicurio Registry deployment.

What it checks:

  • Health endpoint (200 OK)

  • System information retrieval

  • Version verification (2.x or 3.x)

Usage (interactive):

./apicurio-verify-registry-version.sh

Usage (automated):

export REGISTRY_URL="https://registry.example.com"
export REGISTRY_VERSION="v3"
export AUTH_ENABLED="true"
export AUTH_TOKEN_URL="https://keycloak.example.com/realms/registry/protocol/openid-connect/token"
export AUTH_CLIENT_ID="admin-client"
export AUTH_CLIENT_SECRET="your-secret"

./apicurio-verify-registry-version.sh

Environment variables:

Variable Description

REGISTRY_URL

Registry base URL (for example, https://registry.example.com)

REGISTRY_VERSION

Registry version to test (default: v3)

AUTH_ENABLED

Set to true to enable OAuth2 authentication

AUTH_TOKEN_URL

OAuth2 token endpoint URL

AUTH_CLIENT_ID

OAuth2 client ID

AUTH_CLIENT_SECRET

OAuth2 client secret

SKIP_TLS_VERIFY

Set to true to skip TLS certificate verification

Exit codes:

  • 0 - All checks passed

  • 1 - One or more checks failed

Script: apicurio-verify-v3-api-features.sh

Purpose: Verifies that v3-specific API features are available and functioning correctly.

What it tests:

  • v3 system endpoints (/system/info, /system/limits)

  • v3 search endpoints (/search/groups, /search/versions)

  • Admin endpoints

Usage (interactive):

./apicurio-verify-v3-api-features.sh

Usage (automated):

export REGISTRY_URL="https://registry-v3.example.com"
export AUTH_ENABLED="true"
export AUTH_TOKEN_URL="https://keycloak.example.com/realms/registry/protocol/openid-connect/token"
export AUTH_CLIENT_ID="admin-client"
export AUTH_CLIENT_SECRET="your-secret"

./apicurio-verify-v3-api-features.sh

Environment variables:

Variable Description

REGISTRY_URL

Registry base URL (for example, https://registry-v3.example.com)

AUTH_ENABLED

Set to true to enable OAuth2 authentication

AUTH_TOKEN_URL

OAuth2 token endpoint URL

AUTH_CLIENT_ID

OAuth2 client ID

AUTH_CLIENT_SECRET

OAuth2 client secret

SKIP_TLS_VERIFY

Set to true to skip TLS certificate verification

Exit codes:

  • 0 - All feature tests passed

  • 1 - One or more feature tests failed

Configuring authentication

All scripts support OAuth2 authentication using client credentials grant type.

Interactive mode (prompts):

If environment variables are not set, scripts prompt for:

  • Auth token endpoint URL

  • Client ID

  • Client secret (hidden input)

Automated mode (environment variables):

For automation, set these environment variables:

export AUTH_ENABLED="true"
export AUTH_TOKEN_URL="https://keycloak.example.com/realms/registry/protocol/openid-connect/token"
export AUTH_CLIENT_ID="admin-client"
export AUTH_CLIENT_SECRET="your-secret"

Unauthenticated deployments:

If your Apicurio Registry does not use authentication:

export AUTH_ENABLED="false"

Alternatively, press Enter when prompted for authentication.

Configuring TLS/HTTPS support

Production (trusted certificates):

The scripts use trusted certificates by default. To configure this explicitly:

export SKIP_TLS_VERIFY="false"

Development (self-signed certificates):

For testing with self-signed certificates:

export SKIP_TLS_VERIFY="true"
Use SKIP_TLS_VERIFY=true only in non-production environments.
Troubleshooting scripts

Issue: "Failed to obtain access token"

Solution:

  • Verify AUTH_TOKEN_URL is correct.

  • Check that client credentials are valid.

  • Confirm the client has appropriate roles (for example, sr-admin).

  • Test manually with curl.

Issue: "Registry is not accessible"

Solution:

  • Verify REGISTRY_URL is correct.

  • Check network connectivity.

  • Confirm the registry is running and healthy.

  • Verify firewall and security group rules.

Issue: "Export file is too small"

Solution:

  • Check that authentication is working.

  • Verify admin permissions.

  • Review registry logs for errors.

  • Confirm the export endpoint is accessible.

Issue: "Import failed"

Solution:

  • Verify the export file is a valid ZIP: unzip -t registry-export.zip

  • Check that registry v3 has sufficient storage.

  • Review registry v3 logs for errors.

  • Confirm registry v3 is healthy before import.

Issue: "Artifact count mismatch"

Solution:

  • Wait a few seconds after import (processing delay).

  • Check import logs for errors.

  • Verify export file integrity.

  • Consider re-exporting and re-importing.

Installing dependencies

All scripts require:

  • bash (version 4.0+)

  • curl

  • jq (for JSON parsing)

  • unzip (optional, for ZIP validation)

Additional resources