The crash happened when the bus with 37 people on board was heading to a holiday spot in Sukabumi region, West Java.
The vehicle was seen speeding downhill and lost control before plunging into a 10-meter-deep ravine.
"There were 37 people on the bus, 21 of them died while the rest were injured," Galih Bayu Raditya, head of the traffic unit at the local police precinct, told AFP.
Victims who were injured had been taken to several local hospitals.
"We believe the accident happened because the brake failed to function," Raditya said, adding that the vehicle's road-worthy certificate had expired in 2016
The bus was part of a four-bus tour for domestic tourists from Jakarta heading to a rafting spot in Pelabuhan Ratu, Sukabumi.
Passengers from other buses who arrived safely at the destination told the police they had seen smoke coming from the engine of the bus before it embarked on the journey.
Authorities have issued repeated warnings that the route where the accident occurred was not suitable for buses due to the narrowness of the road and multiple tight corners.
On Friday, another bus carrying 21 people also crashed in the same region, killing one and injuring the rest.
Transport accidents are common in Indonesia, where buses and trains are often old and badly maintained.
In February at least 27 people died when a bus with 40 domestic tourists on board hit a motorbike and crashed in Subang region, also in West Java.