{"record":{"id":"40686f1820ff84bd","repo":"hashicorp/nomad","slug":"destroynetwork-rpc-not-supported-by-driver","errorCode":null,"errorMessage":"DestroyNetwork RPC not supported by driver","messagePattern":"DestroyNetwork RPC not supported by driver","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/drivers/server.go","lineNumber":435,"sourceCode":"\tif !ok {\n\t\treturn nil, fmt.Errorf(\"CreateNetwork RPC not supported by driver\")\n\t}\n\n\tspec, created, err := nm.CreateNetwork(req.GetAllocId(), networkCreateRequestFromProto(req))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &proto.CreateNetworkResponse{\n\t\tIsolationSpec: NetworkIsolationSpecToProto(spec),\n\t\tCreated:       created,\n\t}, nil\n}\n\nfunc (b *driverPluginServer) DestroyNetwork(ctx context.Context, req *proto.DestroyNetworkRequest) (*proto.DestroyNetworkResponse, error) {\n\tnm, ok := b.impl.(DriverNetworkManager)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"DestroyNetwork RPC not supported by driver\")\n\t}\n\n\terr := nm.DestroyNetwork(req.AllocId, NetworkIsolationSpecFromProto(req.IsolationSpec))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &proto.DestroyNetworkResponse{}, nil\n}\n\nfunc (b *driverPluginServer) Shutdown(ctx context.Context, req *proto.ShutdownRequest) (*proto.ShutdownResponse, error) {\n\t// Shutdown is optional so check if the plugin has implemented\n\t// the Shutdowner interface and simply return if it does not.\n\ts, ok := b.impl.(DriverShutdowner)\n\tif !ok {\n\t\treturn &proto.ShutdownResponse{}, nil\n\t}\n","sourceCodeStart":417,"sourceCodeEnd":453,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/plugins/drivers/server.go#L417-L453","documentation":"Driver server capability guard in DestroyNetwork: the driver plugin does not implement DriverNetworkManager, so network lifecycle RPCs cannot be served. Only drivers that must create their own network namespaces implement it.","triggerScenarios":"Calling DestroyNetwork (network teardown after task exit / alloc GC) against a driver plugin whose implementation does not satisfy DriverNetworkManager.","commonSituations":"Post-stop cleanup of a network namespace for a driver that never supported network isolation; stale hooks calling destroy on an upgraded/downgraded plugin binary without the capability.","solutions":["Use a driver implementing DriverNetworkManager so create/destroy are symmetric.","Upgrade the driver plugin to a version that implements DriverNetworkManager.","Skip network destroy for drivers without the capability; ensure the scheduler does not create network specs for such drivers in the first place."],"exampleFix":"// before\nerr := client.DestroyNetwork(allocID, spec) // against non-network driver\n// after\nif _, ok := drv.(drivers.DriverNetworkManager); ok {\n\terr = client.DestroyNetwork(allocID, spec)\n}","handlingStrategy":"type-guard","validationCode":"// Only call destroy on drivers known to implement network management\nif _, ok := drv.(drivers.DriverNetworkManager); !ok {\n\treturn nil // nothing to tear down\n}","typeGuard":"func supportsNetworkManager(d interface{}) bool {\n\t_, ok := d.(drivers.DriverNetworkManager)\n\treturn ok\n}","tryCatchPattern":"err := client.DestroyNetwork(ctx, req)\nif err != nil && err.Error() == \"DestroyNetwork RPC not supported by driver\" {\n\t// treat as no-op cleanup; log instead of failing GC\n}","preventionTips":["Skip network teardown for drivers that never created a network spec.","Keep driver capability metadata alongside alloc state for cleanup paths.","Upgrade plugin binaries so create/destroy capabilities stay symmetric.","Make GC hooks tolerant of capability-mismatch errors."],"tags":["plugin","driver","network","capability"],"backgroundTag":"capability-not-supported","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}