Commit a schema revision

This document shows you how to commit a schema revision for Pub/Sub topics.

Before you begin

Required roles and permissions

To get the permissions that you need to commit a schema revision and manage schemas, ask your administrator to grant you thePub/Sub Editor (roles/pubsub.editor) IAM role on your project. For more information about granting roles, seeManage access to projects, folders, and organizations.

This predefined role contains the permissions required to commit a schema revision and manage schemas. To see the exact permissions that are required, expand theRequired permissions section:

Required permissions

The following permissions are required to commit a schema revision and manage schemas:

  • Create schema:pubsub.schemas.create
  • Attach schema to topic:pubsub.schemas.attach
  • Commit a schema revision:pubsub.schemas.commit
  • Delete a schema or a schema revision:pubsub.schemas.delete
  • Get a schema or schema revisions:pubsub.schemas.get
  • List schemas:pubsub.schemas.list
  • List schema revisions:pubsub.schemas.listRevisions
  • Rollback a schema:pubsub.schemas.rollback
  • Validate a message:pubsub.schemas.validate
  • Get the IAM policy for a schema:pubsub.schemas.getIamPolicy
  • Configure theIAM policy for a schema:pubsub.schemas.setIamPolicy

You might also be able to get these permissions withcustom roles or otherpredefined roles.

You can grant roles and permissions to principals such as users, groups,domains, or service accounts. You can create a schema in one project andattach it to a topic located in a different project.Ensure that you have the required permissions foreach project.

Revise a schema

You can commit a schema revision using theGoogle Cloud console, the gcloud CLI, the Pub/Sub API,or the Cloud Client Libraries.

The following are some guidelines to commit a schema revision:

  • You can revise a schema within specific constraints:

    • For Protocol Buffer schemas, you can add or remove optional fields.You cannot add or delete other fields. You also cannot edit anyexisting field.

    • For Avro schemas, refer to theAvro documentation for rules about schema resolution. A new revision must follow the rules asthough it is both the reader schema and the writer schema.

    • A schema can have a maximum of 20 revisions at one time.If you exceed the limit, delete a schema revision before creating another.

  • Each revision has a unique revision ID associated with it. The revision IDis an auto-generated eight-character UUID.

  • When you update the revision range or the revision of a schema used fortopic validation, it might take a few minutes for the changes to take effect.

Console

To create a schema revision, follow these steps:

  1. In the Google Cloud console, go to thePub/Sub schemas page.

    Go to Schemas

  2. Click theSchema ID of an existing schema.

    TheSchema details page for the schema opens.

  3. ClickCreate revision.

    TheCreate schema revision page opens.

  4. Make changes as required.

    For example, for the sample schema in Avro that you created inCreate a schema, you can add an additional optionalfield calledPrice as follows:

    {"type":"record","name":"Avro","fields":[{"name":"ProductName","type":"string","default":""},{"name":"SKU","type":"int","default":0},{"name":"InStock","type":"boolean","default":false},{"name":"Price","type":"double","default":"0.0"}]}
  5. ClickValidate definition to check if the schema definition is correct.

    Note: The validation check does not check the compatibility of the newrevision with the older revisions.
  6. You can also validate the messages for the schema.

    1. ClickTest message to test a sample message.

    2. In theTest message window, select a type ofMessage encoding.

    3. In theMessage body, enter a test message.

      For example, here's a sample message for the test schema.In this example, select theMessage encoding asJSON.

      {"ProductName":"GreenOnions","SKU":34543,"Price":12,"InStock":true}
    4. ClickTest.

  7. ClickCommit to save the schema.

gcloud

gcloudpubsubschemascommitSCHEMA_ID\--type=SCHEMA_TYPE\--definition=SCHEMA_DEFINITION

Where:

You can also specify the schema definition in file:

gcloudpubsubschemascommitSCHEMA_ID\--type=SCHEMA_TYPE\--definition-file=SCHEMA_DEFINITION_FILE

Where:

  • SCHEMA_TYPE is eitheravro orprotocol-buffer.
  • SCHEMA_DEFINITION_FILE is astring containing the path to thefile with the definition of the schema, formatted according to the chosenschema type.

REST

To commit a schema revision, send a POST request like the following:

POST https://pubsub.googleapis.com/v1/projects/PROJECT_ID/schemas/SCHEMA_ID:commitAuthorization: Bearer $(gcloud auth application-default print-access-token)Content-Type: application/json --data @response-body.json

Specify the following fields in the request body:

{"definition":SCHEMA_DEFINITION"type":SCHEMA_TYPE"name":SCHEMA_NAME}

Where:

  • SCHEMA_TYPE is eitherAVRO orPROTOCOL_BUFFER.
  • SCHEMA_DEFINITION is a string containing the definition ofthe schema, formatted according to the chosenschema type.
  • SCHEMA_NAME is the name of an existing schema.

The response body should contain a JSON representation of aschema resource.For example:

{  "name":SCHEMA_NAME,  "type":SCHEMA_TYPE,  "definition":SCHEMA_DEFINITION  "revisionId":REVISION_ID  "revisionCreateTime":REVISION_CREATE_TIME}

Where:

  • REVISION_ID is the server-generated ID for the revision.
  • REVISION_CREATE_TIME is the ISO 8601 timestamp at which therevision was created.

Go

The following sample uses the major version of the Go Pub/Sub client library (v2). If you are still using the v1 library, seethe migration guide to v2.To see a list of v1 code samples, seethe deprecated code samples.

Before trying this sample, follow the Go setup instructions inQuickstart: Using Client Libraries.For more information, see thePub/Sub Go API reference documentation.

Avro

import("context""fmt""io""os"pubsub"cloud.google.com/go/pubsub/v2/apiv1""cloud.google.com/go/pubsub/v2/apiv1/pubsubpb")// commitAvroSchema commits a new Avro schema revision to an existing schema.funccommitAvroSchema(wio.Writer,projectID,schemaID,avscFilestring)error{// projectID := "my-project-id"// schemaID := "my-schema-id"// avscFile = "path/to/an/avro/schema/file(.avsc)/formatted/in/json"ctx:=context.Background()client,err:=pubsub.NewSchemaClient(ctx)iferr!=nil{returnfmt.Errorf("pubsub.NewSchemaClient: %w",err)}deferclient.Close()// Read an Avro schema file formatted in JSON as a byte slice.avscSource,err:=os.ReadFile(avscFile)iferr!=nil{returnfmt.Errorf("error reading from file: %s",avscFile)}schema:=&pubsubpb.Schema{Name:fmt.Sprintf("projects/%s/schemas/%s",projectID,schemaID),Type:pubsubpb.Schema_AVRO,Definition:string(avscSource),}req:=&pubsubpb.CommitSchemaRequest{Name:fmt.Sprintf("projects/%s/schemas/%s",projectID,schemaID),Schema:schema,}s,err:=client.CommitSchema(ctx,req)iferr!=nil{returnfmt.Errorf("error calling CommitSchema: %w",err)}fmt.Fprintf(w,"Committed a schema using an Avro schema: %#v\n",s)returnnil}

Proto

import("context""fmt""io""os"pubsub"cloud.google.com/go/pubsub/v2/apiv1""cloud.google.com/go/pubsub/v2/apiv1/pubsubpb")// commitProtoSchema commits a new proto schema revision to an existing schema.funccommitProtoSchema(wio.Writer,projectID,schemaID,protoFilestring)error{// projectID := "my-project-id"// schemaID := "my-schema"// protoFile = "path/to/a/proto/schema/file(.proto)/formatted/in/protocol/buffers"ctx:=context.Background()client,err:=pubsub.NewSchemaClient(ctx)iferr!=nil{returnfmt.Errorf("pubsub.NewSchemaClient: %w",err)}deferclient.Close()// Read a proto file as a byte slice.protoSource,err:=os.ReadFile(protoFile)iferr!=nil{returnfmt.Errorf("error reading from file: %s",protoFile)}schema:=&pubsubpb.Schema{// TODO(hongalex): check if name is necessary hereName:fmt.Sprintf("projects/%s/schemas/%s",projectID,schemaID),Type:pubsubpb.Schema_PROTOCOL_BUFFER,Definition:string(protoSource),}req:=&pubsubpb.CommitSchemaRequest{Name:fmt.Sprintf("projects/%s/schemas/%s",projectID,schemaID),Schema:schema,}s,err:=client.CommitSchema(ctx,req)iferr!=nil{returnfmt.Errorf("CommitSchema: %w",err)}fmt.Fprintf(w,"Committed a schema using a protobuf schema: %#v\n",s)returnnil}

C++

Before trying this sample, follow the C++ setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub C++ API reference documentation.

Avro

namespacepubsub=::google::cloud::pubsub;[](pubsub::SchemaServiceClientclient,std::stringconst&project_id,std::stringconst&schema_id,std::stringconst&schema_definition_file){std::stringconstdefinition=ReadFile(schema_definition_file);google::pubsub::v1::CommitSchemaRequestrequest;std::stringconstname=google::cloud::pubsub::Schema(project_id,schema_id).FullName();request.set_name(name);request.mutable_schema()->set_name(name);request.mutable_schema()->set_type(google::pubsub::v1::Schema::AVRO);request.mutable_schema()->set_definition(definition);autoschema=client.CommitSchema(request);if(schema.status().code()==google::cloud::StatusCode::kAlreadyExists){std::cout <<"The schema revision already exists\n";return;}if(!schema)throwstd::move(schema).status();std::cout <<"Schema revision successfully committed: "            <<schema->DebugString() <<"\n";}

Proto

namespacepubsub=::google::cloud::pubsub;[](pubsub::SchemaServiceClientclient,std::stringconst&project_id,std::stringconst&schema_id,std::stringconst&schema_definition_file){std::stringconstdefinition=ReadFile(schema_definition_file);google::pubsub::v1::CommitSchemaRequestrequest;std::stringconstname=google::cloud::pubsub::Schema(project_id,schema_id).FullName();request.set_name(name);request.mutable_schema()->set_name(name);request.mutable_schema()->set_type(google::pubsub::v1::Schema::PROTOCOL_BUFFER);request.mutable_schema()->set_definition(definition);autoschema=client.CommitSchema(request);if(schema.status().code()==google::cloud::StatusCode::kAlreadyExists){std::cout <<"The schema revision already exists\n";return;}if(!schema)throwstd::move(schema).status();std::cout <<"Schema revision successfully committed: "            <<schema->DebugString() <<"\n";}

Java

Before trying this sample, follow the Java setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub Java API reference documentation.

Avro

importcom.google.api.gax.rpc.NotFoundException;importcom.google.cloud.pubsub.v1.SchemaServiceClient;importcom.google.pubsub.v1.ProjectName;importcom.google.pubsub.v1.Schema;importcom.google.pubsub.v1.SchemaName;importjava.io.IOException;importjava.nio.file.Files;importjava.nio.file.Paths;publicclassCommitAvroSchemaExample{publicstaticvoidmain(String...args)throwsException{// TODO(developer): Replace these variables before running the sample.StringprojectId="your-project-id";StringschemaId="your-schema-id";StringavscFile="path/to/an/avro/schema/file/(.avsc)/formatted/in/json";commitAvroSchemaExample(projectId,schemaId,avscFile);}publicstaticSchemacommitAvroSchemaExample(StringprojectId,StringschemaId,StringavscFile)throwsIOException{ProjectNameprojectName=ProjectName.of(projectId);SchemaNameschemaName=SchemaName.of(projectId,schemaId);// Read an Avro schema file formatted in JSON as a string.StringavscSource=newString(Files.readAllBytes(Paths.get(avscFile)));try(SchemaServiceClientschemaServiceClient=SchemaServiceClient.create()){Schemaschema=schemaServiceClient.commitSchema(schemaName.toString(),Schema.newBuilder().setName(schemaName.toString()).setType(Schema.Type.AVRO).setDefinition(avscSource).build());System.out.println("Committed a schema using an Avro schema:\n"+schema);returnschema;}catch(NotFoundExceptione){System.out.println(schemaName+"does not exist.");returnnull;}}}

Proto

importcom.google.api.gax.rpc.NotFoundException;importcom.google.cloud.pubsub.v1.SchemaServiceClient;importcom.google.pubsub.v1.ProjectName;importcom.google.pubsub.v1.Schema;importcom.google.pubsub.v1.SchemaName;importjava.io.IOException;importjava.nio.file.Files;importjava.nio.file.Paths;publicclassCommitProtoSchemaExample{publicstaticvoidmain(String...args)throwsException{// TODO(developer): Replace these variables before running the sample.StringprojectId="your-project-id";StringschemaId="your-schema-id";StringprotoFile="path/to/a/proto/file/(.proto)/formatted/in/protocol/buffers";commitProtoSchemaExample(projectId,schemaId,protoFile);}publicstaticSchemacommitProtoSchemaExample(StringprojectId,StringschemaId,StringprotoFile)throwsIOException{ProjectNameprojectName=ProjectName.of(projectId);SchemaNameschemaName=SchemaName.of(projectId,schemaId);// Read a proto file as a string.StringprotoSource=newString(Files.readAllBytes(Paths.get(protoFile)));try(SchemaServiceClientschemaServiceClient=SchemaServiceClient.create()){Schemaschema=schemaServiceClient.commitSchema(schemaName.toString(),Schema.newBuilder().setName(schemaName.toString()).setType(Schema.Type.PROTOCOL_BUFFER).setDefinition(protoSource).build());System.out.println("Committed a schema using a protobuf schema:\n"+schema);returnschema;}catch(NotFoundExceptione){System.out.println(schemaName+"does not exist.");returnnull;}}}

Python

Before trying this sample, follow the Python setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub Python API reference documentation.

Avro

fromgoogle.api_core.exceptionsimportNotFoundfromgoogle.cloud.pubsubimportSchemaServiceClientfromgoogle.pubsub_v1.typesimportSchema#TODO(developer):Replacethesevariablesbeforerunningthesample.#project_id="your-project-id"#schema_id="your-schema-id"#avsc_file="path/to/an/avro/schema/file/(.avsc)/formatted/in/json"#ReadaJSON-formattedAvroschemafileasastring.withopen(avsc_file,"rb")asf:avsc_source=f.read().decode("utf-8")schema_client=SchemaServiceClient()schema_path=schema_client.schema_path(project_id,schema_id)schema=Schema(name=schema_path,type_=Schema.Type.AVRO,definition=avsc_source)try:result=schema_client.commit_schema(request={"schema":schema,"name":schema_path})print(f"Committed a schema revision using an Avro schema file:\n{result}")returnresultexceptNotFound:print(f"{schema_id} does not exist.")

Proto

fromgoogle.api_core.exceptionsimportNotFoundfromgoogle.cloud.pubsubimportSchemaServiceClientfromgoogle.pubsub_v1.typesimportSchema#TODO(developer):Replacethesevariablesbeforerunningthesample.#project_id="your-project-id"#schema_id="your-schema-id"#proto_file="path/to/a/proto/file/(.proto)/formatted/in/protocol/buffers"#Readaprotobufschemafileasastring.withopen(proto_file,"rb")asf:proto_source=f.read().decode("utf-8")schema_client=SchemaServiceClient()schema_path=schema_client.schema_path(project_id,schema_id)schema=Schema(name=schema_path,type_=Schema.Type.PROTOCOL_BUFFER,definition=proto_source)try:result=schema_client.commit_schema(request={"schema":schema,"name":schema_path})print(f"Committed a schema revision using a protobuf schema file:\n{result}")returnresultexceptNotFound:print(f"{schema_id} does not exist.")

Node.js

Before trying this sample, follow the Node.js setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub Node.js API reference documentation.

Avro

/** * TODO(developer): Uncomment these variables before running the sample. */// const schemaNameOrId = 'YOUR_SCHEMA_NAME_OR_ID';// const avscFile = 'path/to/an/avro/schema/file/(.avsc)/formatted/in/json';// Imports the Google Cloud client libraryconst{PubSub,SchemaTypes}=require('@google-cloud/pubsub');constfs=require('fs');// Creates a client; cache this for further useconstpubSubClient=newPubSub();asyncfunctioncommitAvroSchema(schemaNameOrId,avscFile){// Get the fully qualified schema name.constschema=pubSubClient.schema(schemaNameOrId);constname=awaitschema.getName();// Read the new schema definition from storage.constdefinition=fs.readFileSync(avscFile).toString();// Use the gapic client to commit the new definition.constschemaClient=awaitpubSubClient.getSchemaClient();const[result]=awaitschemaClient.commitSchema({name,schema:{name,type:SchemaTypes.Avro,definition,},});console.log(`Schema${name} committed with revision${result.revisionId}.`);}

Proto

/** * TODO(developer): Uncomment these variables before running the sample. */// const schemaNameOrId = 'YOUR_SCHEMA_NAME_OR_ID';// const protoFile = 'path/to/a/proto/schema/file/(.proto)/formatted/in/protcol/buffers';// Imports the Google Cloud client libraryconst{PubSub,SchemaTypes}=require('@google-cloud/pubsub');constfs=require('fs');// Creates a client; cache this for further useconstpubSubClient=newPubSub();asyncfunctioncommitProtoSchema(schemaNameOrId,protoFile){// Get the fully qualified schema name.constschema=pubSubClient.schema(schemaNameOrId);constname=awaitschema.getName();// Read the new schema definition from storage.constdefinition=fs.readFileSync(protoFile).toString();// Use the gapic client to commit the new definition.constschemaClient=awaitpubSubClient.getSchemaClient();const[result]=awaitschemaClient.commitSchema({name,schema:{name,type:SchemaTypes.ProtocolBuffer,definition,},});console.log(`Schema${name} committed with revision${result.revisionId}.`);}

Node.js

Before trying this sample, follow the Node.js setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub Node.js API reference documentation.

Avro

/** * TODO(developer): Uncomment these variables before running the sample. */// const schemaNameOrId = 'YOUR_SCHEMA_NAME_OR_ID';// const avscFile = 'path/to/an/avro/schema/file/(.avsc)/formatted/in/json';// Imports the Google Cloud client libraryimport{PubSub,SchemaTypes}from'@google-cloud/pubsub';import*asfsfrom'fs';// Creates a client; cache this for further useconstpubSubClient=newPubSub();asyncfunctioncommitAvroSchema(schemaNameOrId:string,avscFile:string){// Get the fully qualified schema name.constschema=pubSubClient.schema(schemaNameOrId);constname=awaitschema.getName();// Read the new schema definition from storage.constdefinition:string=fs.readFileSync(avscFile).toString();// Use the gapic client to commit the new definition.constschemaClient=awaitpubSubClient.getSchemaClient();const[result]=awaitschemaClient.commitSchema({name,schema:{name,type:SchemaTypes.Avro,definition,},});console.log(`Schema${name} committed with revision${result.revisionId}.`);}

Proto

/** * TODO(developer): Uncomment these variables before running the sample. */// const schemaNameOrId = 'YOUR_SCHEMA_NAME_OR_ID';// const protoFile = 'path/to/a/proto/schema/file/(.proto)/formatted/in/protcol/buffers';// Imports the Google Cloud client libraryimport{PubSub,SchemaTypes}from'@google-cloud/pubsub';import*asfsfrom'fs';// Creates a client; cache this for further useconstpubSubClient=newPubSub();asyncfunctioncommitProtoSchema(schemaNameOrId:string,protoFile:string){// Get the fully qualified schema name.constschema=pubSubClient.schema(schemaNameOrId);constname=awaitschema.getName();// Read the new schema definition from storage.constdefinition:string=fs.readFileSync(protoFile).toString();// Use the gapic client to commit the new definition.constschemaClient=awaitpubSubClient.getSchemaClient();const[result]=awaitschemaClient.commitSchema({name,schema:{name,type:SchemaTypes.ProtocolBuffer,definition,},});console.log(`Schema${name} committed with revision${result.revisionId}.`);}

After you commit a schema revision, you cansee the details of the newrevision in theSchemas page.

What's next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026-02-19 UTC.