English
How to use the grpcurl command-line tool to test your gRPC service

Test gRPC services just like testing HTTP APIs with curl — A complete tutorial on the grpcurl tool
1. What is grpcurl?
grpcurl is a command-line tool for interacting with gRPC servers. Its design is inspired by curl, but specifically optimized for the gRPC protocol.
Core Features
| Function | Description |
|---|---|
| Call gRPC method | Call gRPC services just like calling REST APIs with curl. |
| Service Discovery | Automatically retrieve service definitions via gRPC reflection |
| Multi-protocol support | Supports HTTP/2, TLS, Unix Socket |
| Multiple data formats | Supports JSON and Protobuf Text formats |
| Streaming call | Supports server streaming, client streaming, and bidirectional streaming. |
Applicable scenarios
Debugging gRPC services during development
Verify whether the service interface is working properly.
Quickly test API return results
API testing in CI/CD
2. Install grpcurl
Method 1: Install using Go (recommended)
bash
# Install the latest version
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
# Verify installation
~/go/bin/grpcurl --versionOption 2: Using Homebrew (macOS)
bash
brew update
brew install grpcurl
grpcurl --versionMethod 3: Download the precompiled binary
Access GitHub Releases Download the binary file for the corresponding platform.
bash
# Example: Download the Linux amd64 version
curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.9.3/grpcurl_1.9.3_linux_x86_64.tar.gz -o grpcurl.tar.gz
tar -xzf grpcurl.tar.gz
sudo mv grpcurl /usr/local/bin/Verify the installation
bash
grpcurl --version
# grpcurl 1.9.33. Basic Usage
3.1 View service list
bash
# List all services through reflection
grpcurl -plaintext localhost:50051 list
# Output example
# grpc.health.v1.Health
# grpc.reflection.v1alpha.ServerReflection
# discovery.v1.DiscoveryAgent3.2 View service methods
bash
# List all methods of a specific service
grpcurl -plaintext localhost:50051 list discovery.v1.DiscoveryAgent
# Output example
# discovery.v1.DiscoveryAgent.Status
# discovery.v1.DiscoveryAgent.Heartbeat
# discovery.v1.DiscoveryAgent.Reload
# discovery.v1.DiscoveryAgent.Verify
# discovery.v1.DiscoveryAgent.StreamHeartbeat3.3 View Method Details
bash
# View the request/response structure of the method
grpcurl -plaintext localhost:50051 describe discovery.v1.DiscoveryAgent.Status
# Output example
# discovery.v1.DiscoveryAgent.Status is a method:
# rpc Status ( .discovery.v1.StatusRequest ) returns ( .discovery.v1.StatusResponse );3.4 Calling gRPC Methods
bash
# Call with no arguments
grpcurl -plaintext localhost:50051 discovery.v1.DiscoveryAgent/Status
# Call with parameters
grpcurl -plaintext -d '{"timestamp": 1723456789}' localhost:50051 discovery.v1.DiscoveryAgent/Heartbeat4. Unix Socket Debugging (Key!)
4.1 Version Differences
Different versions of grpcurl The support for Unix Socket differs:
| Version | Correct format | Description |
|---|---|---|
| v1.8.7 and below | -unix /path/to/socket | Use -unix Logo |
| v1.9.0 and above | unix:///path/to/socket | Use URL format (Recommend) |
4.2 Invocation method for v1.9.0+
bash
# Basic format: grpcurl [flags] [address] [service/method]
# address format: unix:///path/to/socket (three slashes)
# Basic call
grpcurl -plaintext unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Status
# Call with parameters
grpcurl -plaintext -d '{"timestamp": 1723456789}' unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Heartbeat
# Parameterless call
grpcurl -plaintext -d '{}' unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Reload4.3 Points to Note
| Key points | Explanation |
|---|---|
Must add -plaintext | Unix Socket has no TLS; omitting it will cause a TLS error. |
| Address format | Must use unix:///path/to/socket(three slashes) |
| -d parameter position | Place it before the service name. |
| Service name format | package.Service/Method |
4.4 Common Errors and Solutions
| Error | Reason | Solution |
|---|---|---|
missing port in address | Unused unix:// format | Use unix:///path/to/socket |
first record does not look like a TLS handshake | Not added -plaintext | Add -plaintext Logo |
Too many arguments | Parameter order or format error | Check -d Parameter format |
5. Advanced Usage
5.1 Usage -d @ Read from standard input
When the JSON data is large or contains special characters, you can use -d @ Read from standard input:
bash
# Use echo
echo '{"timestamp": 1723456789}' | grpcurl -plaintext -d @ unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Heartbeat
# Use here-document
grpcurl -plaintext -d @ unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Heartbeat <<EOF
{"timestamp": 1723456789}
EOF
# Read from file
grpcurl -plaintext -d @ unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Heartbeat < request.json5.2 Using reflection vs using proto files
Method 1: Use reflection (recommended, requires server-side support)
bash
grpcurl -plaintext localhost:50051 list
grpcurl -plaintext localhost:50051 describe discovery.v1.DiscoveryAgentMethod 2: Use a proto file (when reflection is unavailable)
bash
grpcurl -plaintext -proto api/v1/discovery.proto \
-import-path ./api/v1 \
localhost:50051 discovery.v1.DiscoveryAgent/Status5.3 Add Custom Header
bash
# Add custom Header
grpcurl -plaintext -H "X-API-Key: abc123" \
localhost:50051 discovery.v1.DiscoveryAgent/Status
# Add multiple Header
grpcurl -plaintext -H "Authorization: Bearer token123" \
-H "X-Request-ID: 12345" \
localhost:50051 discovery.v1.DiscoveryAgent/Status5.4 Streaming Invocation
bash
# Server-side streaming (Server Streaming)
grpcurl -plaintext -d '{}' localhost:50051 package.Service/ServerStream
# Client Streaming (Client Streaming)
grpcurl -plaintext -d @ localhost:50051 package.Service/ClientStream <<EOF
{"msg": "hello"}
{"msg": "world"}
EOF6. Practical Tips
6.1 Formatted Output
bash
# Pretty-print the output with jq
grpcurl -plaintext unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Status | jq .
# Extract only specific fields
grpcurl -plaintext unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Status | jq '.modules'6.2 Output as Protobuf Text format
bash
grpcurl -format text -plaintext localhost:50051 discovery.v1.DiscoveryAgent/Status6.3 Debugging Request/Response
bash
# Enable verbose output
grpcurl -v -plaintext localhost:50051 discovery.v1.DiscoveryAgent/Status
# View request/response headers
grpcurl -vv -plaintext localhost:50051 discovery.v1.DiscoveryAgent/Status6.4 Set Timeout
bash
# Connection timeout 10 seconds, total timeout 30 seconds
grpcurl -connect-timeout 10 -max-time 30 \
-plaintext localhost:50051 discovery.v1.DiscoveryAgent/Status7. Using in a Makefile
Complete example
makefile
# grpcurl test command
grpcurl-status:
grpcurl -plaintext unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Status
grpcurl-heartbeat:
grpcurl -plaintext -d '{"timestamp": 1723456789}' unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Heartbeat
grpcurl-reload:
grpcurl -plaintext -d '{}' unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Reload
grpcurl-verify:
grpcurl -plaintext -d '{"discovery_data": ""}' unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Verify
# Version that reads data from a file
grpcurl-heartbeat-file:
grpcurl -plaintext -d @ unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Heartbeat < request.jsonUsage example
bash
make grpcurl-status
make grpcurl-heartbeat
make grpcurl-reload8. Comparison with curl
| Function | curl | grpcurl |
|---|---|---|
| Protocol | HTTP/1.1, HTTP/2 | HTTP/2 (gRPC) |
| Data format | JSON, XML, Form | JSON, Protobuf |
| Service Discovery | OpenAPI/Swagger | gRPC reflection |
| Unix Socket | --unix-socket | unix:///path |
| Streaming | ❌ | ✅ (bidirectional stream) |
| TLS | ✅ | ✅ |
9. Frequently Asked Questions FAQ
Q1:grpcurl report Too many arguments
Reason: The parameter format is incorrect.
Solution:
Check
-dWhether the parameters are correctly parsedUse
-d @Read data from standard input
Q2: Unix Socket error missing port in address
Reason: The correct Unix Socket address format was not used.
Solution:
bash
# Correct format (v1.9.0+)
grpcurl -plaintext unix:///tmp/socket.sock service/methodQ3: Report first record does not look like a TLS handshake
Reason: Not added -plaintext Sign.
Solution:
bash
grpcurl -plaintext localhost:50051 service/methodQ4: How to check the grpcurl version?
bash
grpcurl --versionQ5: What should I do if reflection is not enabled on the server?
Use -proto Specify the proto file:
bash
grpcurl -plaintext -proto api/v1/service.proto -import-path ./api/v1 localhost:50051 package.Service/Method