CheckID does not have associated TTL

Viewed 3330

I'm trying to utilize Consul .NET API to register and fire health checks via TTL. First I'm registering my service with following code:

var address = node.Address;
var id = ServiceId(address);
var registration = new AgentServiceRegistration
{
    ID = id,
    Name = node.ClusterName,
    Address = node.Address.Host,
    Port = node.Address.Port.Value,
    Check = new AgentServiceCheck
    {
        TTL = settings.AliveInterval, // 10sec
        DeregisterCriticalServiceAfter = settings.AliveTimeout, // 60sec
    }
};    
// first, try to deregister service, if it has been registered previously
await consul.Agent.ServiceDeregister(registration.ID);
await consul.Agent.ServiceRegister(registration);

Right afterwards, I'm trying to fire a TTL via:

await consul.Agent.PassTTL("service:" + ServiceId(addr), string.Empty);

However, what I end up with is an exception thrown during PassTTL: Consul.ConsulRequestException: Unexpected response, status code InternalServerError: CheckID "service:{service-id}" does not have associated TTL

And the related log from consul agent itself:

[ERR] http: Request PUT /v1/agent/check/pass/service:{service-id}, error: CheckID "service:{service-id}" does not have associated TTL from=127.0.0.1:25419

I'd like to know what I'm doing wrong here.

I'm using consul agent -dev (version: 1.0.1) and Nuget package Consul (version: 0.7.2.3).

3 Answers

Turns out AgentServiceRegistration.Check property is pretty useless. I've achieved the expected result with CheckRegister method.

Here's the code

var registration = new AgentServiceRegistration
{
    ID = "serviceId",
    Name = node.ClusterName,
    Address = node.Address.Host,
    Port = node.Address.Port.Value
};    
// first, try to deregister service, if it has been registered previously
await consul.Agent.ServiceDeregister(registration.ID);
await consul.Agent.ServiceRegister(registration);
await consul.Agent.CheckRegister(new AgentCheckRegistration()
{
    ID = "checkId",
    Name = "Check Name",
    Status = HealthStatus.Passing,
    TTL = settings.AliveInterval,
    ServiceID = "serviceId",
    DeregisterCriticalServiceAfter = settings.AliveTimeout, // 60sec
})

Now you can pass TTL via

await consul.Agent.PassTTL("checkId", string.Empty);

Just be sure to deregister your check afterwards

It looks like my example was missing a crucial detail here: a ServiceId(address) method was constructing a service ID in form of protocol://service@host:port/ which resulted in Consul complaining about lack of TTL. Changing it to service@host:port seems to fix the error.

I guess in this case a consul error message was very misleading.

Check if id format is:

"service:{service id}:{number}"

In your case, you must pass:

"service:" + ServiceId(addr) + ":1"

as your check id.

Related