I am running a headless Raspberry PI 3, and I want it to automatically accept pairings from any device.

I saw this answer in an identical question:

Automatically accepting Bluetooth connections on a Pi 3

But it seems to be a bit outdated and some of the used commands don't seem to exist.

I am running the 2016-05-27-raspbian-jessie.img OS image.

  • What do you mean by "some of the used commands don't seem to exist"? What exactly didn't work for you? – Dmitry Grigoryev Sep 27 '16 at 11:34
  • 1
    If I remember correctly, bluetooth-agent, but I am not sure. – Gilad Naaman Sep 27 '16 at 13:15

Since bluetooth-agent command doesn't exist on Jessie, the modern way is to pipe relevant commands to bluetoothctl. Based on this SO question, the following script should enable automatic pairing without manual pin entry:

sudo bluetoothctl <<EOF
power on
discoverable on
pairable on
agent NoInputNoOutput
| improve this answer | |
  • 1
    This worked for making my RPi Zero W discoverable on boot. I had previously updated my Bluetooth config via the steps outlined here and with this script. – charliesneath Dec 6 '18 at 2:22
  • This works, but do you mind telling me how to make the raspberry pi auto-trust the device after pairing? Thanks – Daniele Segato Jun 17 '19 at 16:08
  • It seems this allows pairing, but does not authorize connections for lack of an agent. I believe the agent part of this script does not work properly. When I run this script, I get No agent is registered, it seems the default-agent command runs to fast. When I input the commands manually, it does not give this error, but once I quit bluetoothctl it unregisters the agent and trying to connect fails. If I leave bluetoothctl running, I get a prompt asking whether to trust the connection, which is not so NoInputNoOutput as you'd hope... – Matthijs Kooijman Jul 8 '19 at 22:25
  • I suspect the NoInputNoOutput is not so much an authorization policy, but part of the bluetooth protocol to figure out what type of authorization mechanisms (e.g. can a pin be used?) are available. – Matthijs Kooijman Jul 8 '19 at 22:27
  • 1
    Probably, but then you'd have to keep feeding yes's for all pairing attempts (and I'm not entirely sure if that works from stdin or perhaps the script tries to be smart and tries to open the terminal directly rather than stdin (that also happens sometimes)... Have not tried this, though, I ended up using the python script from gist.github.com/mill1000/74c7473ee3b4a5b13f6325e9994ff84c – Matthijs Kooijman Jul 9 '19 at 10:05

I just used a fresh install of 2016-09-23-raspbian-jessie-lite.img to try it without any additional updates. No apt-get update no apt-get install bluez-utils or anything. This single command makes the Pi discoverable and pairable. Without an agent to control who can connect, it just lets anyone:

sudo hciconfig hci0 piscan
| improve this answer | |

Raspbian - Jessie

sudo apt-get install expect


#!/usr/bin/expect -f
set prompt "#"
spawn sudo bluetoothctl
sleep 1
expect -re $prompt
sleep 1
send "agent NoInputNoOutput\r"
sleep 2
expect "Agent registered"
send "default-agent\r"
expect -re $prompt
sleep 3
expect eof
| improve this answer | |
  • 1
    An answer that consists of code only is not very explicit so please provide some more detailed explanation on your answer. Also indent your code block to make it appear like code; use 4 spaces or a tab, at your preference. – user29510 Nov 1 '17 at 14:47

I was facing the same issue and found this method to work (RasPi 3, Model B, Raspbian 9 Stretch)

I am using Raspberry Pi as an IoT EDGE Device and needed it to accept Bluetooth Pair Requests without intervention. I have an Android App that communicates text information to the Pi via Bluetooth and my problem statement needed any Android device to connect.

Firstly, I am not running any separate Bluetooth Agents (No Blueman, infact I had to remove it)

Edited the .bashrc file at

    sudo nano /home/pi/.bashrc

Added two commands to this at the end

    sudo hciconfig hci0 piscan 
    sudo hciconfig hci0 sspmode 1

piscan makes Raspberry Pi Bluetooth discoverable

sspmode 1 enables 'Secure Simple Pairing' which is the same type of method used by your Bluetooth Earphones or Speakers (basically devices that don't have a display where you can confirm PIN). And since these commands are in .bashrc they run at boot.

Run Bluetooth Script. Pair. Although there is a pop-up asking me to confirm, I can communicate messages to and from the Pi with my app

Note : hci0 may not be the same throughout, could be hci1, hci2 please check by running hciconfig on your CLI

This is almost like a contraption, and I am not sure if there are any unknown repercussions, but it works. Any improvements are appreciated

| improve this answer | |

One simple way is Just to remove the Blueman if you have installed it by using

sudo apt remove blueman 

And remove the Bluetooth logo from the top menu by right click and remove.

And install bluedot using

sudo pip3 install bluedot

for more about bluedot click here

import time
from bluedot.btcomm import BluetoothServer
import os
import bluetooth

def data_received(data):

os.system('bluetoothctl discoverable on && bluetoothctl agent NoInputNoOutput')
s = BluetoothServer(data_received)

Now In Android phone go to Bluetooth settings and pair raspberry Pi

And if you will send data it will print on the terminal you can check it's working or not by using this application if you didn't develop your own.

| improve this answer | |
  • Raspbian Jessie, used by the questioner, is outdated since 2020-01-01 and not supported anymore. Its repository is archived. – Ingo Aug 15 at 8:59
  • I have the same Error and I took 2 days to search and resolve it and I just posted here so someone have the same error it will help – Sejpalsinh Jadeja Aug 15 at 15:04
  • What operating system and version do you use? You should edit your answer and mention it. – Ingo Aug 16 at 8:02

You may take a peek at the source code of EcoDroidLink. It accepts Bluetooth connections without the need to log in.

EDIT: By popular demand, here are code excerpts of the edl_agent module that makes this happen.

# - automate the agent for running on a headless Pi - to answer pair and connection requests without a blocking query

import dbus
import dbus.service
import dbus.mainloop.glib
import bluezutils

BUS_NAME = 'org.bluez'
AGENT_INTERFACE = 'org.bluez.Agent1'
AGENT_PATH = "/test/agent"

bus = None
device_obj = None
dev_path = None

def set_trusted(path):
    props = dbus.Interface(bus.get_object("org.bluez", path),
    props.Set("org.bluez.Device1", "Trusted", True)

def dev_connect(path):
    dev = dbus.Interface(bus.get_object("org.bluez", path),

class Rejected(dbus.DBusException):
    _dbus_error_name = "org.bluez.Error.Rejected"

class Agent(dbus.service.Object):
    exit_on_release = True

    def set_exit_on_release(self, exit_on_release):
        self.exit_on_release = exit_on_release

                    in_signature="", out_signature="")
    def Release(self):
        if self.exit_on_release:

                    in_signature="os", out_signature="")
    def AuthorizeService(self, device, uuid):
        printlog("AuthorizeService (%s, %s)" % (device, uuid))
        authorize = "yes" #ask("Authorize connection (yes/no): ")
        if (authorize == "yes"):
        raise Rejected("Connection rejected by user")

                    in_signature="o", out_signature="s")
    def RequestPinCode(self, device):
        printlog("RequestPinCode (%s)" % (device))
        return "0000" #ask("Enter PIN Code: ")

                    in_signature="o", out_signature="u")
    def RequestPasskey(self, device):
        printlog("RequestPasskey (%s)" % (device))
        passkey = "0000" #ask("Enter passkey: ")
        return dbus.UInt32(passkey)

                    in_signature="ouq", out_signature="")
    def DisplayPasskey(self, device, passkey, entered):
        printlog("DisplayPasskey (%s, %06u entered %u)" %
                        (device, passkey, entered))

                    in_signature="os", out_signature="")
    def DisplayPinCode(self, device, pincode):
        printlog("DisplayPinCode (%s, %s)" % (device, pincode))

                    in_signature="ou", out_signature="")
    def RequestConfirmation(self, device, passkey):
        printlog("RequestConfirmation (%s, %06d)" % (device, passkey))
        confirm = "yes" #ask("Confirm passkey (yes/no): ")
        if (confirm == "yes"):
        raise Rejected("Passkey doesn't match")

                    in_signature="o", out_signature="")
    def RequestAuthorization(self, device):
        printlog("RequestAuthorization (%s)" % (device))
        auth = "yes" #ask("Authorize? (yes/no): ")
        if (auth == "yes"):
        raise Rejected("Pairing rejected")

                    in_signature="", out_signature="")
    def Cancel(self):
| improve this answer | |
  • 1
    Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference. – Jacobm001 Aug 11 '17 at 17:37
  • @Jacobm001 I added code excerpts. Is that better now? – Serge Stroobandt Aug 12 '17 at 8:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.