{"record":{"id":"99a72674ed74f149","repo":"grpc/grpc-java","slug":"the-transport-factory-is-closed-99a726","errorCode":null,"errorMessage":"The transport factory is closed.","messagePattern":"The transport factory is closed\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"cronet/src/main/java/io/grpc/cronet/CronetChannelBuilder.java","lineNumber":276,"sourceCode":"        boolean useGetForSafeMethods,\n        boolean usePutForIdempotentMethods) {\n      usingSharedScheduler = timeoutService == null;\n      this.timeoutService = usingSharedScheduler\n          ? SharedResourceHolder.get(GrpcUtil.TIMER_SERVICE) : timeoutService;\n      this.maxMessageSize = maxMessageSize;\n      this.alwaysUsePut = alwaysUsePut;\n      this.streamFactory = streamFactory;\n      this.executor = Preconditions.checkNotNull(executor, \"executor\");\n      this.transportTracer = Preconditions.checkNotNull(transportTracer, \"transportTracer\");\n      this.useGetForSafeMethods = useGetForSafeMethods;\n      this.usePutForIdempotentMethods = usePutForIdempotentMethods;\n    }\n\n    @Override\n    public ConnectionClientTransport newClientTransport(\n        SocketAddress addr, ClientTransportOptions options, ChannelLogger channelLogger) {\n      if (closed) {\n        throw new IllegalStateException(\"The transport factory is closed.\");\n      }\n      InetSocketAddress inetSocketAddr = (InetSocketAddress) addr;\n      return new CronetClientTransport(streamFactory, inetSocketAddr, options.getAuthority(),\n          options.getUserAgent(), options.getEagAttributes(), executor, maxMessageSize,\n          alwaysUsePut, transportTracer, useGetForSafeMethods, usePutForIdempotentMethods);\n    }\n\n    @Override\n    public ScheduledExecutorService getScheduledExecutorService() {\n      return timeoutService;\n    }\n\n    @Override\n    public SwapChannelCredentialsResult swapChannelCredentials(ChannelCredentials channelCreds) {\n      return null;\n    }\n\n    @Override","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/cronet/src/main/java/io/grpc/cronet/CronetChannelBuilder.java#L258-L294","documentation":"CronetChannelBuilder's internal transport factory is closed when the builder's built channel is shut down; after that, any attempt to create a new client transport through the same factory throws IllegalStateException. This is a lifecycle guard preventing transport creation on a torn-down builder/channel.","triggerScenarios":"Calling newClientTransport (e.g. by opening a new RPC via the channel's transport) after the CronetChannelBuilder's transport factory has been closed — typically after channel shutdown.","commonSituations":"Reusing a channel (or its builder) after shutdown() to issue more RPCs; a race where shutdown happens while a new call is being created.","solutions":["Create a new channel via CronetChannelBuilder.forAddress(...) instead of reusing the closed one.","Ensure all RPCs are issued before calling channel shutdown, or keep the channel open as long as it is used.","Guard concurrent shutdown vs. new-call creation with application-level synchronization or an atomic 'closed' check."],"exampleFix":"// before\nchannel.shutdown();\nstub.someRpc(request); // IllegalStateException\n// after\nstub.someRpc(request);\nchannel.shutdown();","handlingStrategy":"validation","validationCode":"if (channel.isShutdown() || channel.isTerminated()) { channel = CronetChannelBuilder.forAddress(host, port, engine).build(); }","typeGuard":null,"tryCatchPattern":"try { stub.call(req); } catch (IllegalStateException e) { if (e.getMessage().contains(\"transport factory is closed\")) { channel = rebuildChannel(); } else { throw e; } }","preventionTips":["Never reuse a channel after shutdown()","Check channel.isShutdown() before issuing RPCs","Manage channel lifecycle in a single owner component"],"tags":["grpc","cronet","lifecycle","illegal-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}