Failed to get SMS provider

I am trying to test SMS MFA using a local instance of supabase (v2.34.3). Below is my configuration
[auth.sms.test_otp]
"my_phone_number" = "123456"

# Configure MFA via Phone Messaging
[auth.mfa.phone]
enroll_enabled = true
verify_enabled = true
otp_length = 6
template = "Your code is {{ .Code }}"
max_frequency = "5s"
[auth.sms.test_otp]
"my_phone_number" = "123456"

# Configure MFA via Phone Messaging
[auth.mfa.phone]
enroll_enabled = true
verify_enabled = true
otp_length = 6
template = "Your code is {{ .Code }}"
max_frequency = "5s"
I'm able to enroll a SMS factor but am getting the following error when calling the challenge API
code: "unexpected_failure"
name: "AuthApiError"
status: 500
__isAuthError: true
message: "Failed to get SMS provider"
code: "unexpected_failure"
name: "AuthApiError"
status: 500
__isAuthError: true
message: "Failed to get SMS provider"
do i need to set a provider in my config.toml? if so—how can I do that? I've previously attempted the above configuration in combination with a dummy twilio provider configuration and was getting a AuthAPIError (500)
[auth.sms.twilio]
enabled = true
account_sid = ""
message_service_sid = ""
auth_token = ""
[auth.sms.twilio]
enabled = true
account_sid = ""
message_service_sid = ""
auth_token = ""
2 Replies
rajat
rajatOP5d ago
@inder sorry for the tag but I saw you were able to help in another thread regarding test_otp, i was wondering if you possibly have any insights here
inder
inder5d ago
Ya i joined this thread because I wanted to test this first. Will get back to you later. Hey, you're right about supabase asking for a sms provider. But this can be overriden by using sms-hook
[auth.hook.send_sms]
enabled = true
uri = "http://host.docker.internal:54321/functions/v1/send_sms"
secrets= "v1,whsec_e1f71eeba662929cc5dac676cb9e53a5"
[auth.hook.send_sms]
enabled = true
uri = "http://host.docker.internal:54321/functions/v1/send_sms"
secrets= "v1,whsec_e1f71eeba662929cc5dac676cb9e53a5"
The downside is that your predefined otp won't work. It will be dynamic everytime. You'll have to create a edge function locally and in this function you can log the otp which is recieved and use that for testing Here is a sample function code. I hardcoded values as this was just for quick testing. You should pass secret via env. In the container logs, you'll see the otp
import "jsr:@supabase/functions-js/edge-runtime.d.ts"
import { Webhook } from 'https://esm.sh/standardwebhooks@1.0.0'

console.log("Hello from Functions!")

Deno.serve(async (req) => {
const payload = await req.text()
const base64_secret = "v1,whsec_e1f71eeba662929cc5dac676cb9e53a5".replace('v1,whsec_', '')
const headers = Object.fromEntries(req.headers)
const wh = new Webhook(base64_secret)

const { user, sms } = wh.verify(payload, headers)
console.log(`Your OTP is: ${sms.otp}`);

return new Response(
JSON.stringify({}),
{
status: 200,
headers: {
'Content-Type': 'application/json',
},
}
)
})
import "jsr:@supabase/functions-js/edge-runtime.d.ts"
import { Webhook } from 'https://esm.sh/standardwebhooks@1.0.0'

console.log("Hello from Functions!")

Deno.serve(async (req) => {
const payload = await req.text()
const base64_secret = "v1,whsec_e1f71eeba662929cc5dac676cb9e53a5".replace('v1,whsec_', '')
const headers = Object.fromEntries(req.headers)
const wh = new Webhook(base64_secret)

const { user, sms } = wh.verify(payload, headers)
console.log(`Your OTP is: ${sms.otp}`);

return new Response(
JSON.stringify({}),
{
status: 200,
headers: {
'Content-Type': 'application/json',
},
}
)
})
You can also send this otp in an email to mailpit which is already available with supabase locally, so that you don't have to switch back and forth between browser and terminal

Did you find this page helpful?