Let's troubleshoot some Signed Embedding (formerly known as SSO Embedding).

This is forever a work-in-progress. Please submit an edit!

What's going on?

The iframe isn't loading as desired

Open the browser dev tools and take a look at the network tab as an Signed Embed URL is loaded into your iframe. What do you see?

There is no request for the Signed Embed URL (like /login/embed/...)

First, double-check that your dev tools' Network tab is not filtered! (e.g. to XHR requests only. Look for an "All" filter if so)

Some browsers hide the request from the dev tools when the request is blocked due security options like X-Frame-Options.

Generate a new Signed Embed URL, but open it in a new tab with the dev tools open instead of embedding it.

Look for an HTTP response header of X-Frame-Options

This header is present and set to SAMEORIGIN

Proceed from the last step as though this request/response was there.

This header is present and set to DENY

Looker does not set this value. Customer-hosted configurations may set up proxies in front of Looker which add these by default. Check that this is not the case.

This header is NOT present

Some other mechanism is blocking the request. Check for:

  • A content security policy header on the parent or ancestor page that may be blocking the request, such as Content-Security-Policy: frame-src
  • Browser extensions that may be blocking the requests
  • Is it possible the client application code is not actually embedding the URL? Try embedding it yourself by adding an <iframe src="..."></iframe> element yourself in the DOM/Inspect tab of the developer tools.
The request for the Signed Embed URL (like /login/embed/...) results in a 404 Is your URL encoding of the embed path using lowercases? (like %2fembed%2f... instead of %2Fembed%2F...) Looker doesn't like those, switch to using uppercase.
The request for the Signed Embed URL (like /login/embed/...) results in a 3xx redirect to Location: of either /login or the homepage (Redirects to /login are most common, but the homepage will be used if you have an active session. Keep in mind that the homepage can be customized based on administrative settings.)

The Signed Embed authentication is not working. Generate a new Signed Embed URL and enter it into the Embed URI Validator at /admin/embed

The Embed URI Validator is not present

Embedding isn't enabled. Enable embedding :)

Embed URI is valid

Hmm, the earlier request should have worked :-/

If the error is known to be intermittent: You may be skipping the URL encoding step after you base64 encode your signature. If so, you would occasionally see + characters in your URL instead of %2B (or spaces in your signature if you are looking at them from the Looker logs). Double-check your URL generation code to ensure you are applying URL encoding to your already base64-encoded signature.

Uh oh, something went wrong!

In addition to adjusting your URL to this situation, please file a bug with chat support for this, as seeing this error indicates a need to enhance the Embed URI Validator.

Check if your URL or JSON encoding is malformed

This code snippet can help you quickly check a URL's encoding for common issues.

var url = "" if (!url.split("?")[1]){console.error("No querystring!")} else{url.split("?")[1].split("&").map(pair=>pair.split("=")).map(([key,value])=>[key,caught(decodeURIComponent)(value)]).map(([key,value])=>[key,(value.message || {signature:1}[key]) ? value : caught(JSON.parse)(value)])} function caught(fn){return x=>{try{return fn(x)}catch(e){return e}}}
Embed URI is not valid: 'nonce' param already used this hour: '...'

Did you really generate a new URL to put into the validator? If so, is your code to generate URLs actually generating nonces?

Embed URI is not valid: 'signature' param failed to authenticate: '...' <<<<<<< HEAD:signed-embed-troubleshooting.html

The signature does not correspond to the passed parameters. Check if the Signed Embed Tool is able to generate a working signature.

The signatures generated by the Signed Embed Tool also fail to validate

You are probably using an incorrect embed secret. Since there is no way to confirm the current secret, you will instead have to reset the embed secret. (Be careful if there are already other applications using Signed Embedding, as they will need to get the new secret.)

=======

The signature does not correspond to the passed parameters. Check if the SSO Embed Tool is able to generate a working signature.

The signatures generated by the SSO Embed Tool also fail to validate

You may be using an incorrect embed secret or incorrect signing algorithm.

Looker supports both HMAC-SHA-1 and HMAC-SHA-256 signing algorithms, and the choice of algorithm is bound to the secret. While the UI exclusively creates HMAC-SHA-1 bound secrets, the API defaults to HMAC-SHA-256 bound secrets.

You may wish to reset your embed secret, or try signing with each algorithm, if it is convenient.

If neither algorithm works and/or you elect to reset your embed secret, be careful - if there are already other applications using SSO Embedding, they will need to get the new secret too.

>>>>>>> bff727a35ab77f466163441640510060f5251e87:sso-embed-troubleshooting.html
The signatures generated by the Signed Embed Tool do validate

Have your application log or dump the parameters it is using, and string that it is signing.

Next, use the "Properties" button in the Signed Embed Tool to pass in all the same parameter values (such as timestamp and nonce), and then generate a URL with the tool, and look at the console for the correct string you should be signing.

Finally, compare this to the one your application is logging.

The strings to sign match between my application and the Signed Embed Tool

If the strings to sign match, and the secrets match, then the implementation of the signing algorithm is off. See our sample code for various languages

The strings to sign do not match between my application and the Signed Embed Tool

Adjust your application to generate the same string. Note that the strings must be byte-for-byte identical, including the order of parameters.

Missing required parameter: force_logout_login

First, of course, check to make your URL has force_logout_login parameter

If your URL does seem to have the force_logout_login parameter, ensure you haven't accidentally encoded or skipped the "?" to actually start your querystring. It can get confusing since the embed path has querystring parameters of its own!

This request includes invalid params: ["embed_domain"]

You are attempting to set the embed_domain in the wrong place.

The embed_domain is expected to be a parameter on your embed_path (which gets URL encoded), and NOT on the overall Signed Embed authentication URL.

Embed URI is not valid: Invalid host: foo.com (Use bar.com instead)

The hostname (bar.com) in the Host header of the HTTP request received by the Looker instance does not match the hostname (foo.com) in the signature (and in the hostname in the test URI sent to the Embed URI Validator)

First, if you have multiple domain names that resolve to your instance, make sure you are accessing the Embed URI Validator via the one that is used in the Signed Embed Request. (I.e., test from https://foo.com/admin/embed , even if you normally administer the instance via bar.com)

Then, if the error remains the same, check whether you have configured a proxy or load balancer in front of Looker which is dropping or rewriting the Host header in the forwarded request. If so, the best solution is to reconfigure the proxy to forward the request with the same Host header.

Other errors...

The remainder of errors reported by the Embed URI Validator generally tell you what you need to fix.

The request for the Signed Embed URL (like /login/embed/...) results in a 3xx redirect to the Location of your "embed path"

The Signed Embed authentication is working. Let's drill in on what happens next!

Look at the subsequent request to the URL indicated in the "Location" HTTP response header (your "embed path" URL)

There is no request for the embed path URL

First, double-check that your dev tools' Network tab is not filtered! (e.g. to XHR requests only. Look for an "All" filter if so)

Some browsers hide the request from the dev tools when the request is blocked due security options like X-Frame-Options.

Generate a new Signed Embed URL, but open it in a new tab with the dev tools open instead of embedding it.

Is the embed path that you are redirected to an `http://` URL instead of `https://`. If so, your instance is probably using the `no-ssl` startup flag, but should be using the `ssl-provided-externally-by` flag instead. (Or, the correct flag is being used, but the provided value is problematic.)

Look for an HTTP response header of X-Frame-Options

This header is present and set to SAMEORIGIN

Proceed from the last step as though this request/response was there.

This header is present and set to DENY

Looker does not set this value. Customer-hosted configurations may set up proxies in front of Looker which add these by default. Check that this is not the case.

This header is NOT present

Some other mechanism is blocking the request. Check for:

  • A content security policy header on the parent or ancestor page that may be blocking the request, such as Content-Security-Policy: frame-src
  • Browser extensions that may be blocking the requests
The embed path request results in a 401 response

The browser is likely blocking the setting of third-party cookies.

If the affected browser is primarily Safari, this can be resolved by either changing browser settings to allow third-party cookies, or changing DNS entries to make Looker available under the same domain as the parent page (if Looker hosts the instance, speak to the account manager)

If there are issues with Chrome and the instance is self-hosted, check whether the session cookies returned in the SSO Embded URL have a "samesite=none" flag. If not, this could be caused by incorrectly runningthe instance with the `no-ssl` startup flag )prefer `ssl-provided-externally-by` instead). Alternately, a proxy/load balancer could also be removing the samesite flag.

The embed path request either results in a 200 with HTTP Response header of "X-Frame-Options: SAMEORIGIN", or redirects to one that does

What is the URL pattern for this request?

`/dashboards/*` , `/looks/*` , `/explore/*` , or `/query/*`

`/embed` should be pre-pended to this path to make it an embeddable request.

`/embed/dashboards/*` , `/embed/looks/*` , `/embed/explore/*` , or `/embed/query/*`

Looker allows embedding these paths, and so it does not set a prohibitive X-Frame-Options HTTP response header for these requests. Customer-hosted configurations may set up proxies in front of Looker which add these by default. Check that this is not the case.

None of the above

Looker does not support embedding these types of content (as of v5.8)

The embed path request results in a 3xx or 4xx response

This is a content/user permissions issue. The below list of possible problems is non-exhaustive. What content are you embedding?

An explore or LookML dashboard (URL like /dashboards/model::dashboard_name)
  • Does the user have the access_data permission (in the Signed Embed permissions or via a group_id)
  • Does the user have the explore/see_lookml_dashboards permission, as appropriate for the content type (in the Signed Embed permissions or via a group_id)
  • Does the user have access to the relevant model (in the Signed Embed modelset or via a group_id)
  • Does the relevant model exist in production (and not just in your dev mode)
A look or user-defined dashboard (URL like /dashboards/123)

Ensure the user has the access_data, and the see_looks/see_user_dashboards permission, either directly through the Signed Embed URL "permissions" parameter, or through a role through a group assigned via the group_ids parameter.

If the content is in a shared space, use the Signed Embed URL "group_ids" parameter to assign the embed user to a group that has access to that shared space (or move/copy the content to a more appropriate shared space).

If the content is in an embed group space, make sure the Signed Embed URL has the right "external_group_id"

(For all tiles to also be accessible, relevant models will also need to be permissioned, either directly or through groups)

The embed path request results in a 200 or redirects to a request that does, but then the page navigates to /embed which returns a 404 response

The browser is sending a cookie for an expired session

  • The session_length Signed Embed parameter may be set to a super short value
  • There may be multiple iframes/tabs involved in a race condition to set the session. If you have multiple iframes on the page, make sure that one always loads first, then skip the Signed Embed Authentication step for the subsequent iframes and set them directly to the embed_path
  • The browser may be blocking the setting of third-party cookies (but previously had set them in some other context). This should be confirmed by clearing all cookies/storage and reproducing the more common error that occurs when third party cookies are blocked
The embed path request results in a 200, or redirects to one that does, and the content renders, but with errors
Firefox hidden iframe bug?

WIP

Some tiles are missing? => Model permissions

WIP

Elements are unexpectedly missing? => Someone set their color to white?

Check the colors defined in the dashboard's embed settings

The request for the Signed Embed URL (like /login/embed/...) results in a 5xx

Check the possible causes below, and if it's not one of these, please file a bug!

  • Is the path part of the URL > 2048 bytes? [Puma limitation]
  • Is the query part of the URL > 10 * 1024 bytes? [Puma limitation]
  • Is there a mismatch between the type of any user attribute (as defined at /admin/user_attributes) and as provided in the querystring argument?
The iframe is loading fine, but cross-frame events aren't working as desired

Things to check: