Migrating from Apicurio Registry 2.6.3 to Apicurio Registry 3.x

You can migrate from Apicurio Registry 2.6.3 to Apicurio Registry 3.x by deploying a new 3.x instance, exporting and importing your persisted data, and updating your client applications.

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.

For general versioning policy, upgrade guidance within the 3.x series, and rollback procedures, see [versioning-support-policy_registry].

Changes in Apicurio Registry 3.x

Apicurio Registry 3.x introduces a redesigned data model, a reworked REST API, and a refreshed SDK ecosystem. These changes require you to deploy a new 3.x instance, migrate your persisted content, and update your client applications and automation.

When you migrate 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). You can prepare governance metadata, rules, and branch structures before you add the first version. Additional highlights include:

  • You manage artifact metadata independently from version metadata.

  • Groups and artifacts support custom labels for improved categorization.

  • You can 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 optimizes stability and maintainability. The redesigned architecture reduces startup times for large installations.

Architectural changes in v3

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

You deploy the user interface as a separate container, which provides more deployment flexibility and enables 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 for Java, TypeScript, Python, and Go provide lightweight, type-safe clients with minimal dependencies and consistent naming.

Migration planning

You can choose from two migration approaches depending on your architecture and availability requirements. Review both approaches and select the one that best fits your environment.

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 dual running 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 must:

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

  • Verify that client applications connect to Apicurio Registry 3.x after the data migration completes. For minimal downtime migrations, verify that 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 step with client updates where possible. See Updating Apicurio Registry configuration.

    Minimal downtime migration

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

    Maintenance window migration

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

Migrating with minimal downtime

You can migrate from Apicurio Registry 2.6.3 to 3.x with minimal downtime by using a load balancer to manage traffic routing. This phase-based workflow 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)

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

Infrastructure:

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

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

  • Load balancer capacity for routing traffic

  • Network connectivity between all components

Storage requirements:

  • v2 database or storage: existing size

  • v3 database or storage: approximately the 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

Table 1. Prerequisites
Requirement Description

Staging environment

A staging environment to test the complete migration workflow before production.

Load balancer

nginx, HAProxy, or a similar tool for traffic management.

Administrative access

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

Database or storage

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

Backup

A current backup of 2.6.3 data.

Rollback plan

A documented procedure to revert to v2 if needed.

Test as much of the migration as possible in a staging environment before you migrate in production.
Procedure

Phase 1: Preparation

  1. Deploy the load balancer.

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

    1. Deploy the load balancer.

    2. Configure routing to 2.6.3.

    3. Update client applications to connect through the load balancer.

    4. Validate that all traffic flows correctly.

    See Updating registry configuration for load balancer configuration examples.

  2. Prepare the 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. You can reuse 2.6.3 certificates.

    • Configure the OAuth2/OIDC authentication provider.

    See Updating registry configuration for detailed configuration changes.

    Checkpoint: v2 traffic flows through the load balancer and v3 infrastructure is ready.

Phase 2: Pre-migration validation

  1. Enable read-only mode.

    Configure the load balancer to block write operations while it allows 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 is active and write operations are blocked. Baseline is documented and 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 is complete and the data snapshot is captured.

  2. Deploy Apicurio Registry 3.x.

    Deploy Apicurio Registry 3.x by using the infrastructure that you 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 is 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 is complete and ready for validation.

  4. Validate the 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 the traffic switch until all checks pass.

    Checkpoint: v3 has all data, data metrics match v2, and the deployment is ready for traffic switch.

Phase 4: Traffic switch

  1. Switch the load balancer to Apicurio Registry 3.x.

    Update the load balancer configuration to route to Apicurio Registry 3.x and enable read and 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 can 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 is minimal.

    Checkpoint: All traffic routes to v3 and write operations are resumed.

  2. Verify traffic to the v3 deployment.

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

    For the verification procedure, see Migration scripts reference.

    Checkpoint: v3 is accessible, write operations work, and no errors appear in the 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 the v3 registry.

  2. Test v3 Core API functionality.

    Verify that 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 work correctly.

  3. Run smoke tests.

    Execute production smoke tests to validate critical functionality:

    1. Test critical client applications.

    2. Verify that Kafka SerDes applications work (if applicable).

    3. Check authentication and authorization.

    4. Monitor error rates and performance metrics.

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

    Checkpoint: All smoke tests passed and production traffic is 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 by switching the 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 is stable for 1-7 days and no rollback is needed.

Phase 7: Cleanup

  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 is complete and v2 is decommissioned.

Verification

After you complete all phases, verify the following:

  • All client applications connect to Apicurio Registry 3.x successfully.

  • No increase in error rates compared to the v2 baseline.

  • Artifact counts and global rules match the pre-migration baseline.

A key advantage of the parallel deployment approach is the ability to roll back quickly if issues arise.

Table 2. Rolling back to 2.6.3
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 that was created in 3.x since migration.

  • Decide on a 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 you switch production traffic.

  • Run comprehensive smoke tests after migration.

Reduces the likelihood that a rollback is required.

Migrating within a maintenance window

For environments where downtime is acceptable, you can follow this simpler sequential process to migrate from Apicurio Registry 2.6.3 to 3.x.

Prerequisites
  • You performed a dry run migration in a staging environment to estimate the timing of the data export and import phases accurately.

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

  2. Export data from Apicurio Registry 2.6.3 by 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 by using the import script. See Migration scripts reference.

  6. Validate the import by 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.

Verification
  • Verify that all client applications connect to Apicurio Registry 3.x successfully.

  • Verify that artifact counts match the pre-migration baseline.

  • Verify that no increase in error rates occurs.

Migrating Apicurio Registry data

You can 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, which ensures that downstream Kafka payloads remain compatible.

You must use the export and import procedure for migration. Apicurio Registry 3.x cannot directly read 2.6.3 storage because the underlying data structures 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. You cannot reuse the v2 topic.

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

Apicurio Registry 3.x accepts the export archive that is 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
  • The source Apicurio Registry 2.6.3 server and the destination 3.x server are both running.

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

  • If you use OAuth2 authentication, you have valid client credentials with the 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 by using the export script:

    ./apicurio-export-registry-data.sh

    The script performs the following actions:

    • 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 by using the import script:

    ./apicurio-import-registry-data.sh

    The script performs the following actions:

    • Validates that 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 by using the verification script:

    ./apicurio-verify-registry-version.sh

    The script performs the following 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.

Verification
  • Verify that artifact counts in v3 match the v2 baseline.

  • Verify that global rules are configured correctly in v3.

  • Verify that sample artifacts contain the expected content and metadata.

Additional resources

Client application backward compatibility

Apicurio Registry 3.x maintains backward compatibility with v2 client libraries and SerDes. You can continue to use v2 clients with a v3 registry during your migration period, which allows you to update clients gradually.

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

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

  • v2 SerDes libraries: continue to work with the v3 registry.

  • v3 SerDes: can consume v2 client Kafka messages with proper configuration.

  • No immediate client updates required: you can update clients gradually during the migration period.

This backward compatibility enables you to:

  1. Migrate the registry to v3 first.

  2. Test with existing v2 clients.

  3. Gradually update clients to v3 libraries over time.

You can choose from two client migration strategies.

Gradual migration

Migrate the registry first, then update clients incrementally. Deploy Apicurio Registry 3.x, verify that v2 clients continue to work, update high-priority clients to v3 SerDes or SDKs, gradually migrate remaining clients, and deprecate v2 API access after you update all clients. This approach provides lower risk because clients continue to work during migration, a flexible timeline for client updates, and easier rollback if issues occur.

Big-bang migration

Update all clients and the registry simultaneously. Prepare all client updates in advance, deploy Apicurio Registry 3.x, deploy updated client applications, and verify that all integrations work. This approach provides a clean cutover to v3 with no mixed v2/v3 client environment, but requires higher complexity and coordination and is more difficult to troubleshoot if issues arise.

Migrating Kafka SerDes applications

You can update your Kafka SerDes applications from Apicurio Registry 2.6.3 to 3.x by updating Maven dependencies, reconfiguring SerDes properties, and updating TLS settings.

Prerequisites
  • You have existing Kafka SerDes applications that use Apicurio Registry 2.6.3 libraries.

  • You have access to the source code and build configuration for each application.

  • You installed the required dependencies for running migration scripts. See Installing dependencies.

Procedure
  1. Update your Maven dependency coordinates from v2 to v3.

    Replace the v2 SerDes dependency:

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

    With the v3 SerDes dependency:

    <dependency>
        <groupId>io.apicurio</groupId>
        <artifactId>apicurio-registry-avro-serde-kafka</artifactId>
        <version>3.3.0</version>
    </dependency>
    Artifact IDs changed in v3. The v2 artifact ID is apicurio-registry-serdes-avro-serde, while v3 uses apicurio-registry-avro-serde-kafka.
  2. Update your SerDes configuration properties for v3.

    Replace the v2 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");

    With the v3 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");

    For a detailed comparison of all changed properties, see Client migration configuration reference.

  3. Update your TLS configuration.

    Replace the v2 system-property-based TLS configuration:

    // 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");

    With the v3 SerdeConfig-based configuration:

    // 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 differs from v2, which uses only system properties.
Verification
  • Verify that v3 consumers read messages that v2 producers produced.

  • Verify that v2 consumers read messages that v3 producers produced.

  • Verify that mixed-environment deployments (v2 and v3 clients) operate without data loss.

Migrating REST API and SDK client applications

You can update applications that use the Apicurio Registry REST API directly by updating SDK dependencies, reconfiguring TLS settings, and updating OAuth2/OIDC authentication.

Prerequisites
  • You have existing applications that use the Apicurio Registry 2.6.3 REST API or Java SDK.

  • You have access to the source code or deployment configuration for each application.

Procedure
  1. Update your SDK Maven dependency coordinates from v2 to v3.

    Replace the v2 SDK dependency:

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

    With the v3 SDK dependency:

    <dependency>
        <groupId>io.apicurio</groupId>
        <artifactId>apicurio-registry-java-sdk</artifactId>
        <version>3.3.0</version>
    </dependency>
  2. Update your TLS configuration.

    Replace the v2 system-property-based TLS configuration:

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

    With the v3 RegistryClientOptions-based configuration:

    // 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);
  3. Update your OAuth2/OIDC authentication configuration.

    Replace the v2 authentication setup:

    import io.apicurio.rest.client.auth.OidcAuth;
    import io.apicurio.rest.client.spi.ApicurioHttpClientFactory;
    
    String authServerUrl = "https://keycloak.example.com/realms/registry";
    ApicurioHttpClient httpClient = ApicurioHttpClientFactory.create(authServerUrl,
        new AuthErrorHandler());
    Auth auth = new OidcAuth(httpClient, clientId, clientSecret, null, null);
    RegistryClient client = RegistryClientFactory.create(registryUrl, Collections.emptyMap(), auth);

    With the v3 authentication setup:

    import io.apicurio.registry.client.RegistryClientFactory;
    import io.apicurio.registry.client.RegistryClientOptions;
    
    String tokenEndpoint = "https://keycloak.example.com/realms/registry/protocol/openid-connect/token";
    RegistryClientOptions options = RegistryClientOptions.create(registryUrl)
        .oauth2(tokenEndpoint, clientId, clientSecret, null);
    RegistryClient client = RegistryClientFactory.create(options);

    For a detailed comparison of all authentication changes, see Client migration configuration reference.

Verification
  • Verify that REST API calls to v3 endpoints return expected results.

  • Verify that authenticated requests succeed with the new OAuth2 configuration.

  • Verify that v2 API backward compatibility endpoints respond correctly.

Client migration configuration reference

The following tables summarize the configuration property changes between Apicurio Registry 2.6.3 and Apicurio Registry 3.x for SerDes applications, REST API clients, and authentication.

Table 3. SerDes configuration property changes
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 that use either ID type, which ensures compatibility during migration. If your v2 applications explicitly set USE_ID=contentId, you can remove this configuration in v3 because it is now the default.
Table 4. REST API client authentication changes
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)

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

  • v3 consumers read messages that v2 producers produce.

  • v2 consumers read messages that v3 producers produce.

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

This compatibility helps you avoid data loss during migration.

Configuration property changes

Configuration keys in Apicurio Registry 3.x adopt a unified apicurio. namespace and reorganize authentication, eventing, UI, and storage settings. The following tables map v2 properties to their v3 equivalents.

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

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.

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

Table 5. KafkaSQL storage properties
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

Not applicable. Remove this property. In v3, the consumer group ID is always auto-generated. Use APICURIO_KAFKASQL_CONSUMER_GROUP_PREFIX to set a recognizable prefix if needed.

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.
Table 6. Authentication and authorization properties
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 by using a separate property.
Table 7. API and deletion properties
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=*

TLS configuration remains unchanged between v2 and v3 for server-side settings.

Table 8. TLS/HTTPS properties
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.
Additional resources

KafkaSQL storage changes in Apicurio Registry 3.x

Apicurio Registry 3.x completely re-engineers the KafkaSQL storage implementation with significant architectural improvements. If you use KafkaSQL storage, understand these changes before you configure the v3 journal topic.

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.

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

Snapshotting creates periodic database snapshots of the registry state, which provides the following benefits:

  • Faster startup times: The 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 or more).

  • Long-running deployments with growing journal topics.

  • Situations that need faster registry startup and 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 that 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 documentation for more information on how to configure and use the snapshotting feature.

Configuring the KafkaSQL journal topic

You can create and configure the v3 KafkaSQL journal topic with the correct cleanup policy and retention settings.

Prerequisites
  • You have access to Kafka administrative tools (kafka-topics.sh).

  • You understand the KafkaSQL architectural changes in v3. See KafkaSQL storage changes.

Procedure
  1. Create the v3 KafkaSQL journal topic with the correct settings.

    kafka-topics.sh --bootstrap-server kafka:9092 --create \
      --topic kafkasql-journal-v3 \
      --partitions 1 \
      --replication-factor 3 \
      --config cleanup.policy=delete \
      --config retention.ms=-1 \
      --config retention.bytes=-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.

    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.
  2. Verify the topic configuration.

    kafka-topics.sh --bootstrap-server kafka:9092 --describe \
      --topic kafkasql-journal-v3
    
    # Expected output:
    #   cleanup.policy=delete
    #   retention.ms=-1
    #   retention.bytes=-1
Verification
  • Verify that the topic uses cleanup.policy=delete (not compact).

  • Verify that retention.ms=-1 and retention.bytes=-1 are set for infinite retention.

  • Verify that the topic is accessible from the Apicurio Registry 3.x deployment.

Verifying migration configuration

You can verify your v3 configuration by following this checklist to ensure that all properties are correctly updated before you switch production traffic.

Procedure
  1. Inventory all configuration files, including deployment manifests, application.properties, and environment variables.

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

  3. Update configuration for v3 deployment:

    • Storage: Change the database name or topic name.

    • Authentication: Update to the full realm URL format.

    • Properties: Apply the apicurio.* namespace.

  4. Deploy v3 to a 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.

Verification
  • Verify that Apicurio Registry 3.x starts without configuration errors.

  • Verify that all API endpoints respond correctly.

  • Verify that authentication and authorization work as expected.

Resolving configuration issues

If you encounter configuration issues during migration, use the following guidance to diagnose and resolve common problems.

v3 fails to start with "Storage not configured"

Symptoms:

  • Registry pod or 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
v3 authentication fails with "User is not authenticated"

Symptoms:

  • All API requests return 401 Unauthorized.

  • Valid access tokens are rejected.

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

Solution:

Verify 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 that Keycloak is accessible from the registry container:

curl -k https://keycloak:8443/realms/registry/.well-known/openid-configuration
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
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=*
Role-based authorization does not work

Symptoms:

  • Users can access the registry but cannot perform admin operations.

  • No 403 Forbidden errors, but operations fail silently.

Cause: Role configuration properties not updated to the 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 that the user has correct roles in Keycloak and the 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 architecture changes

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

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:

  • You deploy and manage two containers instead of one.

  • Additional networking configuration is required.

  • You have more flexible deployment options.

  • You can scale UI and API components independently.

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

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.

Deploying the Apicurio Registry user interface

You can deploy the Apicurio Registry 3.x user interface by choosing a deployment topology, deploying the UI container, and optionally enabling Designer functionality.

Prerequisites
  • You deployed Apicurio Registry 3.x (the backend API container).

  • You have access to your container orchestration platform (Docker Compose, Kubernetes, or OpenShift).

Procedure
  1. Choose a deployment topology.

    Option 1: Separate subdomains

    Deploy the UI and API to separate subdomains:

    # UI accessible at: https://registry-ui.example.com
    apicurio-registry-ui:
      image: apicurio/apicurio-registry-ui:3.3.0
      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.3.0
      ports:
        - "443:8443"

    Benefits: clean separation of concerns, independent DNS, easier independent scaling.

    Option 2: Co-located with reverse proxy

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

    services:
      apicurio-registry:
        image: apicurio/apicurio-registry:3.3.0
        environment:
          - apicurio.app.context-path=/app/
          - QUARKUS_HTTP_CORS_ORIGINS=*
    
      apicurio-registry-ui:
        image: apicurio/apicurio-registry-ui:3.3.0
        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.

  2. Deploy the UI container with the REGISTRY_API_URL environment variable pointing to your backend API.

  3. Configure UI settings on the application (API) container by using apicurio.ui.* properties.

    For a complete list of available properties, see User interface configuration properties.

  4. Optional: Enable Designer functionality.

    Designer functionality requires you to enable content mutability for artifact versions:

    apicurio.rest.mutability.artifact-version-content.enabled=true

    When enabled, users with the developer or admin role can create draft versions, edit draft content by using the visual editor, save changes iteratively, and finalize drafts to create immutable versions.

Verification
  • Verify that the UI loads and displays the registry dashboard.

  • Verify that the UI connects to the backend API and displays artifacts.

  • If Designer is enabled, verify that you can create and edit draft versions.

User interface configuration properties

The following tables list the configuration properties for the Apicurio Registry 3.x user interface. Configure most settings on the application (API) container. The UI container environment variables override application settings when set.

Configure the following properties on the apicurio-registry (API) container:

Table 9. Application container properties
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 the UI

false

apicurio.ui.features.breadcrumbs

Show breadcrumbs in the UI

true

apicurio.ui.features.settings

Show the Settings tab in the UI

true

Example application container configuration:

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

The UI container environment variables override application configuration. You typically do not need to set these variables.

Table 10. 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 the UI context path

REGISTRY_NAV_PREFIX_PATH

Override for the navigation prefix path

REGISTRY_DOCS_URL

Override for the documentation URL

REGISTRY_EDITORS_URL

Override for the editors (Designer) URL

REGISTRY_AUTH_URL

Override for the OAuth2/OIDC auth server URL

REGISTRY_AUTH_CLIENT_ID

Override for the 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 by using apicurio.ui.* properties.
Additional resources

Migration scripts reference

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

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 and 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/.

All migration scripts share the following 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 and 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 the 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 a 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 that contains artifact summary and global rules (default: registry-baseline.txt).

Script: apicurio-export-registry-data.sh

Purpose: Exports all data from a 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 that contains the 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 a 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 the 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:

  • The import adds to existing data and does not replace it.

  • The script warns if the 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.

All scripts support OAuth2 authentication by using the client credentials grant type.

Interactive mode (prompts):

If environment variables are not set, scripts prompt for the following information:

  • Auth token endpoint URL.

  • Client ID.

  • Client secret (hidden input).

Automated mode (environment variables):

For automation, set the following 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.

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.
"Failed to obtain access token"

Verify that AUTH_TOKEN_URL is correct. Check that client credentials are valid. Confirm that the client has appropriate roles (for example, sr-admin). Test manually with curl.

"Registry is not accessible"

Verify that REGISTRY_URL is correct. Check network connectivity. Confirm that the registry is running and healthy. Verify firewall and security group rules.

"Export file is too small"

Check that authentication is working. Verify admin permissions. Review registry logs for errors. Confirm that the export endpoint is accessible.

"Import failed"

Verify that 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 that registry v3 is healthy before import.

"Artifact count mismatch"

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 migration scripts require the following tools:

  • bash (version 4.0 or later).

  • curl.

  • jq (for JSON parsing).

  • unzip (optional, for ZIP validation).

Additional resources

Troubleshooting migration issues

If you encounter issues during migration, use the following guidance to diagnose and resolve common problems.

Export fails
  • Verify that the authentication credentials are valid.

  • Verify that 2.6.3 is accessible.

  • Review registry logs for errors.

Import fails
  • Verify that the export file is a valid ZIP format.

  • Verify that Apicurio Registry 3.x has sufficient storage.

  • Review registry v3 logs for specific errors.

  • If a partial import occurred, drop the 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 traffic back to 2.6.3.

  2. Investigate v3 issues.

    Recovery time is 30-60 seconds. Your v2 data remains unchanged because the export operation is read-only.