False context deadline exceeded errors in Go management API

I’m getting constant false context deadline exceeded errors in the User.Roles function in the Go management API.

It receives a context with a 30 second timeout. And it frequently throws the following error:

failed to send the request: Get "<my_auth0_url>/api/v2/users/<userid>/roles?include_totals=true&per_page=50": Post "https://<my_auth0_url>/oauth/token": context deadline exceeded

after just a few seconds.

This is the only function in my app that does this. And they all receive the same context.

I’m initializing the Auth0 management API as follows:

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

auth0Api, err := management.New(
	auth0Domain,
	management.WithClientCredentials(ctx, auth0ClientId, auth0ClientSecret),
)

And I’m calling the User.Roles function as follows:

roles, err := app.auth0Api.User.Roles(r.Context(), id)

The User.Roles function even throws this error if I give it a context with no timeout. For example: context.Background().

What is happening here?

Hey @Outbound5070!

I looked at the code and the documentation and noticed the function may be incorrect. You may be looking for the User.getRoles as per this doc. I found some other go-auth0 docs which may be helpful.

I hope this helps!

Best,
Alex

1 Like

Hi @alex.brett, the documentation you linked to with the getRoles function is for NodeJs. So it doesn’t apply.

I’ve seen the other links you shared. Neither of them describe how to correctly get user roles.

As far as I can tell, the User.Roles function is the one I should be using. And it returns the role data I need. It just doesn’t seem to be working correctly because it throws the context error I described.

Is there another function I should be using?

Or is there another way I can get user role data in my app that doesn’t require the management API? I’d rather not use it.

Also @alex.brett, just to add some context; all requests in my app get the same context with a 30 second timeout.

Including, from the Auth0 Go quickstart:

token, err := app.auth.Exchange(r.Context(), code)
idToken, err := app.auth.VerifyIDToken(r.Context(), token)

And, as I already mentioned, from the Auth0 Go management API documentation:

auth0Api, err := management.New(
	auth0Domain,
	management.WithClientCredentials(ctx, auth0ClientId, auth0ClientSecret),
)

And it also makes DB and S3 calls with the same context.

None of these functions ever throw a context timeout error.

BUT, the management API User.Roles function is the only management API function the app uses.

So it’s possible the problem lies somewhere else in the management API SDK.

@alex.brett can I get an update on this? This is a persistent blocking issue for me. And it’s preventing me from launching.

Or can you at least suggest a workaround so I can get role data in my app without using the management API?

I just need a way to differentiate users based on permissions. If roles aren’t the only option I’m open to alternatives.

Hey @Outbound5070! Apologies for some of the mix ups in my last reply.

Have you tried reproducing the issue on localhost? This could help verify where the issue is occurring.

Here is some example code from the Go SDK with Management API to get a Management API access token: GitHub - auth0/go-auth0: Go SDK for the Auth0 Management API.

package main

import (
	"context"
	"log"

	"github.com/auth0/go-auth0"
	"github.com/auth0/go-auth0/management"
)

func main() {
	// Get these from your Auth0 Application Dashboard.
	// The application needs to be a Machine To Machine authorized
	// to request access tokens for the Auth0 Management API,
	// with the desired permissions (scopes).
	domain := "example.auth0.com"
	clientID := "EXAMPLE_16L9d34h0qe4NVE6SaHxZEid"
	clientSecret := "EXAMPLE_XSQGmnt8JdXs23407hrK6XXXXXXX"

	// Initialize a new client using a domain, client ID and client secret.
	// Alternatively you can specify an access token:
	// `management.WithStaticToken("token")`
	auth0API, err := management.New(
		domain,
		management.WithClientCredentials(context.TODO(), clientID, clientSecret),  // Replace with a Context that better suits your usage
	)
	if err != nil {
		log.Fatalf("failed to initialize the auth0 management API client: %+v", err)
	}

	// Now we can interact with the Auth0 Management API.
	// Example: Creating a new client.
	client := &management.Client{
		Name:        auth0.String("My Client"),
		Description: auth0.String("Client created through the Go SDK"),
	}

	// The passed in client will get hydrated with the response.
	// This means that after this request, we will have access
	// to the client ID on the same client object.
	err = auth0API.Client.Create(context.TODO(), client)  // Replace with a Context that better suits your usage
	if err != nil {
		log.Fatalf("failed to create a new client: %+v", err)
	}

	// Make use of the getter functions to safely access
	// fields without causing a panic due nil pointers.
	log.Printf(
		"Created an auth0 client successfully. The ID is: %q",
		client.GetClientID(),
	)
}

You can use the access token to get user roles from the Management API.

package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://login.auth0.com/api/v2/roles"
  method := "GET"

  client := &http.Client {
  }
  req, err := http.NewRequest(method, url, nil)

  if err != nil {
    fmt.Println(err)
    return
  }
  req.Header.Add("Accept", "application/json")

  res, err := client.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer res.Body.Close()

  body, err := ioutil.ReadAll(res.Body)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(string(body))
}

These examples are from the documentation, please give these a try and let me know if they help!

Best,
Alex

1 Like

Hey @alex.brett, thanks for the follow up.

I ended up removing the management API library completely, and switching to the explicit calls to the management API token and roles endpoints like you suggested.

I had to navigate through some errors in the documentation—the roles endpoint in the Go docs was wrong—but I have it working now. And it doesn’t seem to be throwing the context timeout errors anymore.

I’m going to continue testing it. But for now I’m going to say this is solved.

Thanks again!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.